【UVa 10328】Coin Toss [动态规划 递推][高精度]

UVA - 10328

求至少k个连续硬币为正面的情况数  是有限制的递推DP

我枯了 mian了半天把里面的关系理清楚 然后我高精又双叒写挂了QAQ

把高精+的c.a[i]+=p.a[i]+q.a[i]; 打成 c.a[i]=p.a[i]+q.a[i];我就系个瓜娃几

把至少转为至多   将至少k个连续的H可以转换为→至多n~k个连续→至多n个连续的情况数-至多(k-1)个连续的情况数

dp[i][0/1]表示第i张牌为正/反至多有x个连续H的所有情况

i<=x : dp[i][0]=dp[i-1][0]+dp[i-1][1]

i==x+1 : dp[i][0]=dp[i-1][0]+dp[i-1][1]-1   因为第x+1的位置为H时 它前x个的情况就不要能为全为H的情况 故-1

i>x+1 : dp[i][0]=dp[i-1][0]+dp[i-1][1]-dp[i-x-1][1]  当i-1~i-x的位置全为H时 i的位置不能为H i-x-1一定为T

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define rg register
 4 const int N=100+55;
 5 const int base=10000,power=4;
 6 int n,k;
 7 
 8 template<class t>void rd(t &x)
 9 {
10     x=0;int w=0;char ch=0;
11     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
12     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
13     x=w?-x:x;
14 }
15 
16 struct num{
17     int a[1000];
18     num(){memset(a,0,sizeof(a));}
19     num(int x)
20     {
21         memset(a,0,sizeof(a));
22         int t=0;
23         while(x) a[++t]=x%base,x/=base;
24         a[0]=t;
25     }
26     void print()
27     {
28         printf("%d",a[a[0]]);
29         for(rg int i=a[0]-1;i>=1;--i) printf("%0*d",power,a[i]);
30     }
31 }sum,ans,e;
32 
33 num operator +(const num &p,const num &q)
34 {
35     num c;
36     c.a[0]=max(p.a[0],q.a[0]);
37     for(rg int i=1;i<=c.a[0];++i)
38     {
39         c.a[i]+=p.a[i]+q.a[i];
40         c.a[i+1]+=c.a[i]/base,c.a[i]%=base;
41     }
42     if(c.a[c.a[0]+1]) ++c.a[0];
43     return c;
44 }
45 
46 num operator -(const num &p,const num &q)
47 {
48     num c=p;
49     for(int i=1;i<=c.a[0];++i)
50     {
51         c.a[i]-=q.a[i];
52         if(c.a[i]<0) c.a[i]+=base,--c.a[i+1];
53     }
54     while(c.a[0]>0&&!c.a[c.a[0]]) --c.a[0];
55     return c;
56 }
57 
58 num work(int x)
59 {
60     num f[N][2];
61     f[0][0]=e;
62     for(rg int i=1;i<=n;++i)
63     {
64         sum=f[i-1][0]+f[i-1][1];
65         f[i][1]=sum;
66         if(i<=x) f[i][0]=sum;
67         else if(i==x+1) f[i][0]=sum-e;
68         else if(i>x+1) f[i][0]=sum-f[i-x-1][1];
69     }
70     return f[n][0]+f[n][1];
71 }
72 
73 int main()
74 {
75 //    freopen("testdata.in-3.txt","r",stdin);
76     e=num(1);
77     while(scanf("%d%d",&n,&k)==2)
78     {
79         ans=work(n)-work(k-1);
80         ans.print();
81         printf("
");
82     }
83     return 0; 
84 } 
100昏 DP

原文地址:https://www.cnblogs.com/lxyyyy/p/10777792.html