[高精度+递推] uva 10328 Coin Toss

来源:互联网 发布:java好用的分页插件 编辑:程序博客网 时间:2024/06/05 18:25

题目链接:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1269


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 14 24 34 46 2

Sample Output

1583143


题目意思:

有n张牌,求出至少有k张牌连续是正面的排列的种数。(1=<k<=n<=100)

解题思路:

高精度+递推

显然n张牌总的排列数为2^n,如果减去最多有(k-1)张连续正面的情况,就是最后的结果。

dp[i][0]:表示第i张牌为正面,且最多有k张连续的正面的种数

dp[i][1]=dp[i-1][0]+dp[i-1][1];

dp[i][0] 当i<=k时,dp[i][0]=dp[i-1][0]+dp[i-1][1]

当i==k+1时,dp[i][0]=dp[i-1][0]+dp[i-1][1]-1;

当i>k+1时,dp[i][0]=dp[i-1][0]+dp[i-1][1]-dp[i-k-1][1];

代码:

//#include<CSpreadSheet.h>#include<iostream>#include<cmath>#include<cstdio>#include<sstream>#include<cstdlib>#include<string>#include<string.h>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<set>#include<stack>#include<list>#include<queue>#include<ctime>#include<bitset>#include<cmath>#define eps 1e-6#define INF 0x3f3f3f3f#define PI acos(-1.0)#define ll __int64#define LL long long#define lson l,m,(rt<<1)#define rson m+1,r,(rt<<1)|1#define M 1000000007//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define Maxn 110int dp[Maxn][2][Maxn];// dp[i][0]表示第i个为H,至多出现连续k个连续H,个数int n,k;int temp[Maxn];int ans[Maxn];int res[Maxn];void add(int a[],int b[]) //加法{    int aa=0;    memset(res,0,sizeof(res));    for(int i=100;i>=1;i--)    {        res[i]=(a[i]+b[i]+aa)%10000;        aa=(a[i]+b[i]+aa)/10000;    }}void sub(int a[110],int b[110]) //减法{    int cur=0;    memset(res,0,sizeof(res));    for(int i=100;i>=1;i--)    {        if(a[i]-cur>=b[i])        {            res[i]=a[i]-cur-b[i];            cur=0;        }        else        {            res[i]=a[i]+10000-b[i]-cur;            cur=1;        }    }}int main(){   //freopen("in.txt","r",stdin);   //freopen("out.txt","w",stdout);   while(~scanf("%d%d",&n,&k))   {       memset(dp,0,sizeof(dp));       memset(ans,0,sizeof(ans));       ans[100]=1;       dp[0][0][100]=1;       k--;       for(int i=1;i<=n;i++)       {           add(dp[i-1][0],dp[i-1][1]);           memcpy(dp[i][1],res,sizeof(res));           if(i<=k)           {               add(dp[i-1][0],dp[i-1][1]);               memcpy(dp[i][0],res,sizeof(res));           }           else if(i==k+1)           {               memset(temp,0,sizeof(temp));               temp[100]=1;               add(dp[i-1][0],dp[i-1][1]);               memcpy(dp[i][0],res,sizeof(res));               sub(dp[i][0],temp);               memcpy(dp[i][0],res,sizeof(res));           }           else           {               add(dp[i-1][0],dp[i-1][1]);               memcpy(dp[i][0],res,sizeof(res));               sub(dp[i][0],dp[i-k-1][1]);               memcpy(dp[i][0],res,sizeof(res));           }           add(ans,ans);           memcpy(ans,res,sizeof(res));           int j=1;           while(!ans[j]&&j<=100)                j++;       }       sub(ans,dp[n][0]);       memcpy(ans,res,sizeof(res));       sub(ans,dp[n][1]);       memcpy(ans,res,sizeof(res));       int i=1;       while(!ans[i]&&i<=100)            i++;       printf("%d",ans[i++]);       while(i<=100)            printf("%04d",ans[i++]);       putchar('\n');   }   return 0;}



0 0
原创粉丝点击