本文主要是介绍FZU 2200 cleaning (环形dp),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Accept: 15 Submit: 27
Time Limit: 1000 mSec Memory Limit : 65536 KB
Problem Description
N个人围成一圈在讨论大扫除的事情,需要选出K个人。但是每个人与他距离为2的人存在矛盾,所以这K个人中任意两个人的距离不能为2,他们想知道共有多少种方法。
Input
第一行包含一个数T(T<=100),表示测试数据的个数。
接下来每行有两个数N,K,N表示人数,K表示需要的人数(1<=N<=1000,1<=K<=N)。
Output
输出满足题意的方案数,方案数很大,所以请输出方案数mod 1,000,000,007 后的结果。
Sample Input
Sample Output
Source
FOJ有奖月赛-2015年10月#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int const MAX = 1e3 + 5;
int const MOD = 1e9 + 7;
int dp[2][2][MAX][MAX][2][2];
int n;void UP(int &x, int y)
{x += y;if(x >= MOD)x -= MOD;
}void cal(int a, int b)
{dp[a][b][2][a + b][a][b] = 1;for(int i = 3; i <= 1000; i++){for(int j = 0; j <= 1000; j++){if(j){dp[a][b][i][j][0][1] = dp[a][b][i - 1][j - 1][0][0];dp[a][b][i][j][1][1] = dp[a][b][i - 1][j - 1][0][1];}UP(dp[a][b][i][j][0][0], dp[a][b][i - 1][j][0][0]);UP(dp[a][b][i][j][0][0], dp[a][b][i - 1][j][1][0]);UP(dp[a][b][i][j][1][0], dp[a][b][i - 1][j][0][1]);UP(dp[a][b][i][j][1][0], dp[a][b][i - 1][j][1][1]);}}
}int main()
{int T;scanf("%d", &T);for(int i = 0; i < 2; i ++)for(int j = 0; j < 2; j ++)cal(i, j);while(T --){int k, ans = 0;scanf("%d %d", &n, &k);for(int i = 0; i < 2; i++)for(int j = 0; j < 2; j++)for(int l = 0; l < 2; l++)for(int z = 0; z < 2; z++)if(!((l == 1 && i == 1) || (z == 1 && j == 1)))UP(ans, dp[i][j][n][k][l][z]);printf("%d\n", ans);}
}
这篇关于FZU 2200 cleaning (环形dp)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!