牛飞盘队Cow Frisbee Team

老唐最近迷上了飞盘,约翰想和他一起玩,于是打算从他家的N头奶牛中选出一支队伍。
每只奶牛的能力为整数,第i头奶牛的能力为R i 。飞盘队的队员数量不能少于 1、大于N。
一支队伍的总能力就是所有队员能力的总和。
约翰比较迷信,他的幸运数字是F,所以他要求队伍的总能力必须是F的倍数。请帮他
算一下,符合这个要求的队伍组合有多少?由于这个数字很大,只要输出答案除以 10^8的余
数就可以了。
输入格式
第一行:两个用空格分开的整数:N和F,1≤N≤20001≤F≤1000
第二行到N+1行:第i+1行有一个整数Ri ,表示第i头奶牛的能力,1 ≤Ri≤10^5
输出格式
 第一行:单个整数,表示方案数除以 10^8的余数
样例 
4 5 1 2 8 2 3 (有两种方案都是8 + 2 = 10,只是选的奶牛)
题目描述
农夫顿因开始玩飞盘之后,约翰也打算让奶牛们享受飞盘的乐趣.他要组建一只奶牛飞盘
队.他的N(1≤N≤2000)只奶牛,每只部有一个飞盘水准指数Ri(1≤Ri≤100000).约翰要选出1只或多于1只奶牛来参加他的飞盘队.由于约翰的幸运数字是F(1≤F≤1000),他希望所有奶牛的飞盘水准指数之和是幸运数字的倍数.
帮约翰算算一共有多少种组队方式.
输入输出格式
输入格式:
* Line 1: Two space-separated integers: N and F
* Lines 2..N+1: Line i+1 contains a single integer: R_i
输出格式:
* Line 1: A single integer representing the number of teams FJ can choose, modulo 100,000,000.
输入输出样例
输入样例#14 5 
1 
2 
8 
2 
输出样例#13 
说明
FJ has four cows whose ratings are 1, 2, 8, and 2. He will only accept a team whose rating sum is a multiple of 5.
FJ can pair the 8 and either of the 2's (8 + 2 = 10), or he can use both 2's and the 1 (2 + 2 + 1 = 5).
题目背景

题解:

f[i][j]表示选到前i件物品,%m的余数为j的方案数。

初始条件f[i][a[i]]=1。

转移:f[i][j] += f[i-1][j]+f[i-1][((j-a[i])%m+m)%m];

(分这头牛选或不选两种情况)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<string>
 7 #include<queue>
 8 #define ll long long
 9 #define DB double
10 using namespace std;
11 const ll mod=1e8;
12 const int N=2e3+30;
13 int n,F,a[N];
14 ll f[N][N];
15 int main()
16 {
17     scanf("%d%d",&n,&F);
18     for(int i=1;i<=n;++i) scanf("%d",&a[i]),f[i][a[i]%F]=1;
19     for(int i=1;i<=n;++i)
20      for(int j=0;j<F;++j)
21          f[i][j]=(f[i][j]+f[i-1][j]+f[i-1][((j-a[i])%F+F)%F])%mod;
22     printf("%lld",f[n][0]);
23     return 0;
24 }
25  
View Code