ZOJ 3791 An Easy Game(DP)
2014-06-21 19:43
393 查看
题目链接
题意 : 给你两个长度为N的字符串,将第一个字符串每次只能变化M个,问变换K次之后变成第二个字符串一共有几种方法。
思路 : DP。dp[i][j]表示变了 i 次之后有j个不一样的字母的方法数。
状态转移方程:dp[i+1][j+M-2*k] += (dp[i][j]*(c[j][k]*c[N-j][M-k]) ;
c[j][k]表示的是从j个不匹配的字符中找出k个不匹配,所以c[N-j][M-k]表示的剩下的N-j个中挑出M-k个匹配的进行变换。两者相乘就是组合数,表明这次变换的方法数。
View Code
题意 : 给你两个长度为N的字符串,将第一个字符串每次只能变化M个,问变换K次之后变成第二个字符串一共有几种方法。
思路 : DP。dp[i][j]表示变了 i 次之后有j个不一样的字母的方法数。
状态转移方程:dp[i+1][j+M-2*k] += (dp[i][j]*(c[j][k]*c[N-j][M-k]) ;
c[j][k]表示的是从j个不匹配的字符中找出k个不匹配,所以c[N-j][M-k]表示的剩下的N-j个中挑出M-k个匹配的进行变换。两者相乘就是组合数,表明这次变换的方法数。
#include <stdio.h> #include <string.h> #include <iostream> using namespace std ; long long c[110][110],dp[110][110] ; char sh[110],ch[110] ; void cmn() { for(int i = 0 ; i < 110 ; i++) c[i][0] = 1 ; for(int i = 1 ; i < 110 ; i++) { for(int j = 1 ; j <= i ; j++) c[i][j] = (c[i-1][j-1]+c[i-1][j])%1000000009 ; } } int main() { int N,K,M ; cmn() ; while(~scanf("%d %d %d",&N,&K,&M)) { scanf("%s %s",ch,sh) ; int cnt = 0 ; memset(dp,0,sizeof(dp)) ; for(int i = 0 ; i < N ; i++) if(sh[i] != ch[i]) cnt++ ; dp[0][cnt] = 1 ; for(int i = 0 ; i < K ; i++) { for(int j = 0 ; j <= N ; j++) { for(int k = 0 ; k <= M ; k++) { if(j+M-2*k < 0) break ; if(j+M-2*k > N) continue ; dp[i+1][j+M-2*k] += ((dp[i][j]%1000000009)*(c[j][k]*c[N-j][M-k]%1000000009))%1000000009 ; } } } printf("%lld\n",dp[K][0]) ; } return 0 ; }
View Code
相关文章推荐
- ZOJ 3791 An Easy Game[dp]
- ZOJ_3791 An Easy Game[ 二维dp ]
- ZOJ 3791 An Easy Game[dp]
- ZOJ 3791 An Easy Game DP
- zoj 3791 An Easy Game(dp)
- ZOJ 3791 An Easy Game (DP)
- zoj 3791 An Easy Game dp
- ZOJ_3791_An Easy Game(DP)
- zoj 3791 An Easy Game
- ZOJ 3791 An Easy Game
- ZOJ 3791 An Easy Game
- ZOJ 3791 An Easy Game(dp+组合数)
- ZOJ 3791 An Easy Game
- ZOJ 3791 An Easy Game [组合计数]
- ZOJ 3791 An Easy Game
- zoj 3791 An Easy Game
- zoj3791(An Easy Game) DP
- ZOJ3791 An Easy Game(DP)
- 训练赛 An Easy Game(dp)
- 2014 Super Training #8 C An Easy Game --DP