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
  • 相关阅读:
    Python 学习笔记 11.模块(Module)
    Python 学习笔记 8.引用(Reference)
    Python 学习笔记 9.函数(Function)
    Python 学习笔记 6.List和Tuple
    Python 学习笔记 4.if 表达式
    Python 学习笔记 2.自省
    Python 学习笔记 3.简单类型
    Python 学习笔记 7.Dictionary
    Python 学习笔记 5.对象驻留
    Python 学习笔记 10.类(Class)
  • 原文地址:https://www.cnblogs.com/LMCC1108/p/10937529.html
Copyright © 2011-2022 走看看