• 【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

  • 相关阅读:
    Oracle中job的使用详解
    Control File (二)重建CONTROLFILE --- NORESETLOG
    Oracle Analyze 命令 详解
    深入学习Oracle分区表及分区索引
    B树索引和位图索引的区别!
    RAID0_RAID1_RAID10_RAID5各需几块盘才可组建
    Oracle IO优化心得
    修改dbwr后台进程数量
    查看ORACLE执行计划的几种常用方法
    printf()格式化输出详解及echo带颜色输出
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/10777792.html
Copyright © 2020-2023  润新知