您的位置:首页 > 其它

UVALive 6801

2016-08-24 21:25 246 查看
很水的dp,和学长推了一下午,也是够了。。

dp这个东西一下想明白了就发现很水,重要的是想不出来- -!

第一维代表当前走到了第几步,第二维代表剩余几个1。

状态转移:dp[i][j] += dp[i - 1][j + 1] * (j + 1)(代表前一个选了1,有j+1种选法);dp[i][j] += dp[i - 1][j - 1] * (n - j + 1)(代表前一个选了0,有n-j+1种选法)。

然后最后结果就是走完了k步,剩余0个1,即dp[k][0]。

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <climits>
#include <queue>
using namespace std;
const int MOD = 1000000007;
long long dp[1005][1005];
int x;
int main()
{
int T;
int kase = 0;
scanf("%d", &T);
while(T--)
{
memset(dp, 0, sizeof(dp));
int tmp = 0;
int n, k;
scanf("%d%d", &n, &k);
for(int i = 0; i < n; ++i)
{
scanf("%d", &x);
if(x)
++tmp;
}
dp[0][tmp] = 1;
for(int i = 1; i <= k; ++i)
{
for(int j = 0; j <= n; ++j)
{
if(j - 1 >= 0)
dp[i][j] = (dp[i][j] + dp[i - 1][j - 1] * (n - j + 1)) % MOD;
if(j + 1 <= n)
dp[i][j] = (dp[i][j] + dp[i - 1][j + 1] * (j + 1)) % MOD;
}
}
printf("Case #%d: %lld\n", ++kase, dp[k][0]);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm dp