题解 P2946 【[USACO09MAR]Cow Frisbee Team S】
CCF_zkskyer · · 题解
一、看题
很明显,这是一道USACO的原题,所以我们得先看题面,小心被坑(本蒟蒻就被坑了!!!)
广大群众都看出来这是一道完完全全的01背包,但还是有些不一样,这里不是求能力最大,而是求能整除幸运数F的总能力有几种
二、构思
大部分朋友听到这里后就不会做了,这恰好就中了出题人的下怀,其实啊,我们不妨直接按题目中的条件去试试,没准就过了呢(AC的魔力)
所以,根据题面所说的,可以看出状态转移方程,其实这道题蛮单纯的
状态转移方程如下:
即分奶牛参与或不参与两种情况进行讨论
三、AC代码呈现
#include <bits/stdc++.h>
using namespace std;
const int mod=100000000;//这里定义去模的数,尽量用常数
long long cow[2005],f[2005][2005];//cow[i]指第i头奶牛的能力,f[i][j]是存前i件物品且余数正好为j时的最大值
int main()
{
int N,F;
scanf("%d%d",&N,&F);//输入奶牛数量和幸运数
for (register int i=1;i<=N;i++) //适当的卡
{
scanf("%d",&cow[i]);//输入奶牛能力
cow[i]%=F;//这里可以提前取模,减少时间
}
for (register int i=1;i<=N;i++) f[i][cow[i]]=1;//初始化
for (register int i=1;i<=N;i++)//列举前i件物品
{
for (register int j=0;j<=F-1;j++)//列举余数
{
f[i][j]=((f[i][j]+f[i-1][j])%mod+f[i-1][(j-cow[i]+F)%F])%mod;//状态转移方程应用
}
}
printf("%d",f[N][0]);//注意这里是到前n件物品且余数正好为0时的最大值
return 0;
}
四、请求
本人是中学生,第一次发题解,请大家多多支持,留下你们宝贵的赞,顶我!!!