牛飞盘队(弱鸡的DP自我救赎)

牛飞盘队

题面:

老唐最近迷上了飞盘,约翰想和他一起玩,于是打算从他家的N头奶牛中选出一支队伍。每只奶牛的能力为整数,第i头奶牛的能力为R i 。飞盘队的队员数量不能少于 1、大于N。一支队伍的总能力就是所有队员能力的总和约翰比较迷信,他的幸运数字是F,所以他要求队伍的总能力必须是F的倍数。请帮他
算一下,符合这个要求的队伍组合有多少?由于这个数字很大,只要输出答案除以 10^8的余数就可以了。
输入格式
第一行:两个用空格分开的整数:N和F,1 ≤ N ≤ 2000,1 ≤ F ≤ 1000
第二行到N + 1行:第i + 1行有一个整数R i ,表示第i头奶牛的能力,1 ≤ R i ≤ 10 5
输出格式
 第一行:单个整数,表示方案数除以 10^810 8
的余数
样例 fristeam.in fristeam.out
4 5 1 2 8 2 3 (有两种方案都是8 + 2 = 10,只是选的奶牛)

这个题目格式很sb,直接给飞机票

当然大大大大大佬们会觉得本题相当的简单,但是我真的是一个弱鸡

……仔细想不难想

f[i][j]=(f[i][j]+f[i-1][j]+f[i-1][((j-a[i])%m+m)%m])%MOD;

f[i][j]表示前i个牛飞盘队达到j值得方案数,分别由f[i][j](当前这个牛飞盘本身能达到要求),f[i-1][j]不选用当前这个牛飞盘队,f[i-1]((j-a[i])%m+m)%m

再预处理那些牛飞盘队能满足要求就ok,虽然非常简单但我第一眼想不到……哭了

上代码

#include<bits/stdc++.h>
using namespace std;

const int N = 2010, M = 1010;
const int MOD = 1e8;
int n, m;
int f[N][M], a[N];

int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1; i<=n; i++) 
      scanf("%d",&a[i]),f[i][a[i]%m] = 1;
    for (int i=1; i<=n; i++)
        for (int j=0;j<m;j++)
            f[i][j]=(f[i][j]+f[i-1][j]+f[i-1][((j-a[i])%m+m)%m])%MOD;
    printf("%d\n", f[n][0]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/beautiful_cxw/article/details/81227095
今日推荐