题意:有N(1≤N≤2000)只奶牛,每只奶牛都有一个指数R(1≤R≤100000),请你在这N头牛中选出多于1只牛,使指数之和是一个数F的倍数。求出有多少种方式
错解:0/1背包变形,求种数(可惜超时2个点,并且也会超内存)
正解:标准经典动归,与有道难题火柴游戏类似,都需要用到mod,因为要求出组成的f的倍数,所以方程为f[i][j]:=f[i-1][j]+f[i-1][j+l-(a[i] mod l)) mod l]);要善用mod凑余数的思想,减少复杂度。初值要注意f[0][0]:=1;最后结果f[n][0]-1
#include
#include
int n,f;
int *r;
int CowNumber()
{
int i,j,k;
int **cower;
cower=(int **)malloc(sizeof(int *)*2);
for(i=0;i<2;i++)
cower[i]=(int *)malloc(sizeof(int)*f);
for(i=0;i<2;i++)
for(j=0;j
cower[i][j]=0;
cower[0][0]=1;
cower[1][0]=1;
for(i=0;i
{
for(j=0;j
{
cower[1][(j+r[i])%f]+=cower[0][j];
cower[1][(j+r[i])%f]%=100000000;
}
for(k=0;k
cower[0][k]=cower[1][k];
}
return (cower[1][0]-1);
}
void main()
{
int i;
scanf("%d%d",&n,&f);
r=(int *)malloc(sizeof(int)*n);
for(i=0;i
scanf("%d",&r[i]);
printf("%d\n",CowNumber());
}