您的位置:首页 > 其它

BZOJ 3400: [Usaco2009 Mar]Cow Frisbee Team 奶牛沙盘队 动态规划

2017-03-14 20:00 519 查看
题目链接:这里

Description

农夫顿因开始玩飞盘之后,约翰也打算让奶牛们享受飞盘的乐趣.他要组建一只奶牛飞盘

队.他的N(1≤N≤2000)只奶牛,每只部有一个飞盘水准指数Ri(1≤Ri≤100000).约翰要选出1只或多于1只奶牛来参加他的飞盘队.由于约翰的幸运数字是F(1≤F≤1000),他希望所有奶牛的飞盘水准指数之和是幸运数字的倍数.

帮约翰算算一共有多少种组队方式.

Input

第1行输入N和F,之后N行输入Ri.

Output

组队方式数模10^8取余的结果.


Sample Input

4 5

1

2

8

2

Sample Output

3

HINT

组队方式有(2,3),(3,4),(1,2,4)共三种

题意:有3000只羊,每只羊都有自己的能力值。

问你有多少种选择方案,可以使得羊的能力值之和,是约翰能力值的倍数。

解法:

dp

dp[i][j]表示前i只绵羊,当前mod约翰能力值倍数的为j的方案数。

然后暴力转移

复杂度: O(N*F)

//BZOJ 3400

#include <bits/stdc++.h>
using namespace std;
const int mod = 1e8;
int dp[2][1005]; //dp[i][j]代表前i只绵羊,当前mod约翰能力值倍数为j时的方案数
int n, F;
int now = 1, pre = 0;
void add(int &x, int y){
x += y;
if(x >= mod) x %= mod;
}
int main(){
cin >> n >> F;
//memset(dp, 0, sizeof(dp));
for(int i = 1; i <= n; i++){
int x;
cin >> x;
swap(now, pre);
memset(dp[now], 0, sizeof(dp[now]));
dp[now][x%F]++;
for(int j = 0; j < F; j++){
add(dp[now][j], dp[pre][j]);
add(dp[now][(j+x)%F], dp[pre][j]);
}
}
cout << (dp[now][0] + mod) %mod << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: