1. 程式人生 > >Coin Toss(uva 10328,動態規劃遞迴,限制條件,至少轉至多,高精度)

Coin Toss(uva 10328,動態規劃遞迴,限制條件,至少轉至多,高精度)

有n張牌,求出至少有k張牌連續是正面的排列的種數。(1=<k<=n<=100)

 

Toss is an important part of any event. When everything becomes equal toss is the ultimate decider. Normally a fair coin is used for Toss. A coin has two sides head(H) and tail(T). Superstition may
 work in case of choosing head or tail. If anyone becomes winner choosing head he always wants to choose head. Nobody believes that his winning chance is 50-50. However in this problem we will deal with a fair coin and n times tossing of such a coin. The result
 of such a tossing can be represented by a string. Such as if 3 times tossing is used then there are possible 8 outcomes. HHH HHT HTH HTT THH THT TTH TTT
As the coin is fair we can consider that the probability of each outcome is also equal. For simplicity we can consider that if the same thing is repeated 8 times we can expect to get each possible sequence
 once.
The Problem
In the above example we see 1 sequnce has 3 consecutive H, 3 sequence has 2 consecutive H and 7 sequence has at least single H. You have to generalize it. Suppose a coin is tossed n times. And the same
 process is repeated 2^n times. How many sequence you will get which contains a consequnce of H of length at least k. The Input
The input will start with two positive integer, n and k (1<=k<=n<=100). Input is terminated by EOF.
The Output
For each test case show the result in a line as specified in the problem statement.
Sample Input 4 1
4 2
4 3
4 4
6 2
Sample Output 15
8
3
1
43  
/*
思路: ps(a陣列內部的遞推計算本來應該也用高精度整數來計算,但是被我省略了,因為太懶了) (把至少k個正面)轉換為(至多n個正面)-(至多k-1個正面) 對於(至多n個正面),它等於2^n,考慮到n比較大,用高精度大整數來計算出2^n 對於(至多k-1個正面) 先根據k-1是否為0定義f[1][1]的初始值 f[1][2]肯定為1 ps.陣列的第二維中1代表正,2代表反的總情況數 由於對反面牌沒有要求,所以: 第i次為反情況數=第i-1次為正情況數+第i-1次為反情況數 如果i<=k-1,隨便放,那麼第i次為正情況數=第i-1次為正情況數+第i-1次為反情況數 如果i=(k-1)+1,那麼第i次為正情況數=第i-1次為正情況數+第i-1次為反情況數-1 那個-1是減去前面全是正面的情況

如果i>(k-1)+1,那麼第i次為正情況數=第i-1次為正情況數+第i-1次為反情況數-第i-(k-1)-1次為反情況數 那個-第i-(k-1)-1次為反情況數 是排除第i-(k-1)-1次為反而且中間全是正的情況的情況

 

*/
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn=101;
ll a[maxn][3];
ll big[maxn];
int main()
{
    ll n,k;
    cin>>n>>k;
    big[
1]=1; big[0]=1; for(ll i=1;i<=n;i++) { for(ll i=1;i<=big[0];i++) big[i]*=2; for(ll i=1;i<=big[0];i++) { if(big[i]>=10) { big[i+1]+=big[i]/10; big[i]%=10; } if(big[big[0]+1]>0) big[0]++; } } if(k-1==0) { a[n][1]=0,a[n][2]=1; goto dog; } a[1][1]=1;a[1][2]=1; for(ll i=2;i<=n;i++) { a[i][2]=a[i-1][1]+a[i-1][2]; if(i<=k-1) a[i][1]=a[i-1][1]+a[i-1][2]; else if(i==k-1+1) a[i][1]=a[i-1][1]+a[i-1][2]-1; else a[i][1]=a[i-1][1]+a[i-1][2]-a[i-(k-1)-1][2]; } dog:; big[1]-=a[n][1]+a[n][2]; while(big[1]<0) { big[1]+=pow(10,big[0]-1); big[big[0]]--; if(big[big[0]]==1) { big[0]--; } } for(ll i=1;i<=big[0];i++) { if(big[i]>=10) { big[i+1]+=big[i]/10; big[i]%=10; } if(big[big[0]+1]>0) big[0]++; } for(ll i=big[0];i>=1;i--) printf("%lld",big[i]); return 0; }