zoukankan      html  css  js  c++  java
  • ZOJ

    ZOJ - 4114 Flipping Game 

      题目大意:给出两个串s,t,n个灯泡的序列,1代表开着,0代表关着,一共操作k轮,每轮改变m个灯泡的状态,问最终能把s串变成t串的方案数。

      坤神题解

      很奇特的一种dp,首先状态的定义dp[i][j]是前i轮操作后,有j个灯泡的状态跟最终串不一样的方案数。这样初始化是dp[0][num]=1其他全0,num是s串和t串状态不同的灯泡数目。然后状态的转移,对于每一轮我们枚举有j个灯泡跟最终串状态不一样,然后再枚举上一轮有kk个灯泡与最终串状态不一样,每次操作都会改变灯泡的状态,设上一轮不一样的状态改变了x个,一样的状态改变了y个,那么x,y应该有0<=x<=kk,0<=y<=n-kk,x+y=m,kk-x+y=j,这四个约束条件,而满足约束条件的就是合法的转移过程,也就是dp[i][j]=dp[i-1][kk]*C[kk][x]*C[n-kk][y]最后注意取模。

     1 #include<cstdio>
     2 typedef long long ll; 
     3 const int N=118,mod=998244353;
     4 ll dp[N][N],C[N][N];
     5 char a[N],b[N];
     6 void getC()
     7 {
     8     C[0][0]=1ll;
     9     for(int i=1;i<=100;i++)
    10     {
    11         C[i][0]=1ll;
    12         for(int j=1;j<=i;j++)
    13         {
    14             if(j<=i/2)
    15                 C[i][j]=C[i-1][j]+C[i-1][j-1];
    16             else
    17                 C[i][j]=C[i][i-j];
    18             if(C[i][j]>=mod)
    19                 C[i][j]%=mod;
    20         }
    21     }
    22 }
    23 void init(int n,int k)
    24 {
    25     for(int i=0;i<=k;i++)
    26         for(int j=0;j<=n;j++)
    27             dp[i][j]=0ll;
    28     int num=0;
    29     for(int i=0;i<n;i++)
    30         num+=(a[i]!=b[i]);
    31     dp[0][num]=1;
    32 }
    33 int main()
    34 {
    35     int t,n,m,k,x,y;
    36     getC(); 
    37     scanf("%d",&t);
    38     while(t--)
    39     {
    40         scanf("%d%d%d",&n,&k,&m);
    41         scanf("%s%s",a,b);
    42         init(n,k);
    43         for(int i=1;i<=k;i++)
    44             for(int j=0;j<=n;j++)
    45                 for(int kk=((m+j)&1);kk<=m+j&&kk<=n;kk+=2)
    46                 {//把约束条件联立一下可以得出合法条件下的x,y 
    47                     y=(m+j-kk)/2;
    48                     x=m-y;
    49                     if(x<0||y<0||x>kk||y>n-kk)
    50                         continue;
    51                     dp[i][j]+=dp[i-1][kk]*C[kk][x]%mod*C[n-kk][y]%mod;
    52                     if(dp[i][j]>=mod)
    53                         dp[i][j]%=mod;
    54                 }
    55         printf("%lld
    ",dp[k][0]);
    56     }
    57     return 0;
    58 }
    神奇的dp
  • 相关阅读:
    阅读文献总结笔记11
    阅读文献总结笔记20
    阅读文献总结笔记13
    阅读文献总结笔记19
    阅读文献总结笔记17
    阅读文献总结笔记18
    阅读文献总结笔记15
    java图片以字符串的形式传输
    java与C#对接签名和验签
    SIP代码大全
  • 原文地址:https://www.cnblogs.com/LMCC1108/p/10937529.html
Copyright © 2011-2022 走看看