ZOJ 3791 An Easy Game(dp+组合数)

来源:互联网 发布:淘宝评价不能晒图 编辑:程序博客网 时间:2024/06/05 07:20

题目意思是:给你两串二进制串,每个串有n个,然后让你把第一个串通过移动k次,每次移动m个(就是把0变为1,1变为0操作),可以得到第二个串,让你求出有多少种方法。结果需要取余。

很显然是一个dp,dp[i][j] 表示的是第i次有j个相同了。所以有:

dp[i][j-t+(m-t)] += dp[i][j]*C(n-j, m-t)*C(j, t);

因为每次都是操作m个,所以之前有j个满足,经过反转之后变成j-t+(m-t)个满足条件的t表示满足的条件的,而从j里面选t个变为不符合条件的组合数为C(j, t)。从n-j个不满足条件的选m-t个变为满足条件的组合数为:C(n-j, m-t)。

知道这些就好做了啊。

An Easy Game

Time Limit: 2 Seconds      Memory Limit: 65536 KB

One day, Edward and Flandre play a game. Flandre will show two 01-strings s1 and s2, the lengths of two strings are n. Then, Edward must move exact k steps. In each step, Edward should change exact m positions of s1. That means exact m positions of s1, '0' will be changed to '1' and '1' will be changed to '0'.

The problem comes, how many different ways can Edward change s1 to s2 after k steps? Please calculate the number of the ways mod 1000000009.

Input

Input will consist of multiple test cases and each case will consist of three lines. The first line of each case consist of three integers n (1 ≤ n ≤ 100), k (0 ≤ k ≤ 100), m (0 ≤ m ≤ n). The second line of each case is a 01-string s1. The third line of each case is a 01-string s2.

Output

For each test case, you should output a line consist of the result.

Sample Input

3 2 1100001

Sample Output

2

Hint

100->101->001100->000->001

#include <algorithm>#include <iostream>#include <stdlib.h>#include <string.h>#include <iomanip>#include <stdio.h>#include <string>#include <queue>#include <cmath>#include <stack>#include <map>#include <set>#define eps 1e-4#define M 1000100///#define LL __int64#define LL long long#define INF 0x7ffffff#define PI 3.1415926535898#define Mod 1000000009using namespace std;const int maxn = 210;char s1[maxn], s2[maxn];LL c[maxn][maxn];LL dp[maxn][maxn];void Del(){    for(int i = 0; i <= 200; i ++)        c[i][0] = c[i][i] = 1;    for(int i = 1; i <= 200; i ++)    {        for(int j = 1; j < i; j ++)            c[i][j] = (c[i-1][j-1] + c[i-1][j])%Mod;    }}int main(){    Del();    int n, k, m;    while(cin >>n>>k>>m)    {        cin >>s1;        cin >>s2;        int ans = 0;        for(int i = 0; i < n; i++)            if(s1[i] == s2[i])                ans++;        memset(dp, 0, sizeof(dp));        dp[0][ans] = 1;        for(int i = 0; i < k; i++)        {            for(int j = 0; j <= n; j++)            {                if(dp[i][j] == 0)                    continue;                for(int t = 0; t <= min(j, m); t++)                {                    if(m-t > n-j)                        continue;                    dp[i+1][j-t+(m-t)] = (dp[i+1][j-t+(m-t)] + ((dp[i][j]*c[j][t])%Mod)*c[n-j][m-t]%Mod)%Mod;                }            }        }        cout<<dp[k][n]%Mod<<endl;    }    return 0;}


0 0
原创粉丝点击