太珂怕了……为什么还有大佬用FFT和分治的……
首先如果没有不取的限制的话就是一个裸的背包
然后我们考虑一下,正常的转移的话代码是下面这个样子的
1 for(int i=1;i<=n;++i) 2 for(int j=m;j>=a[i];--j) 3 dp[j]+=dp[j-a[i]];
然后我们如果不考虑某一个物品的话,只要把它的贡献给减掉就可以了
1 for(int j=0;j<=m;++j) f[j]=dp[j]; 2 for(int j=a[i];j<=m;++j) f[j]-=f[j-a[i]];
然后这样叫上去只有80分……
经过冥(kan)思(le)苦(ti)想(jie),我终于知道自己错在哪里了……
本来以为只要最后的答案对10取模就可以了……没想到连过程中都得取模否则会炸精度orz
1 //minamoto 2 #include<bits/stdc++.h> 3 using namespace std; 4 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 5 char buf[1<<21],*p1=buf,*p2=buf; 6 inline int read(){ 7 #define num ch-'0' 8 char ch;bool flag=0;int res; 9 while(!isdigit(ch=getc())) 10 (ch=='-')&&(flag=true); 11 for(res=num;isdigit(ch=getc());res=res*10+num); 12 (flag)&&(res=-res); 13 #undef num 14 return res; 15 } 16 const int N=2005; 17 int dp[N],f[N],a[N],n,m; 18 int main(){ 19 // freopen("testdata.in","r",stdin); 20 n=read(),m=read(); 21 for(int i=1;i<=n;++i) a[i]=read(); 22 dp[0]=1; 23 for(int i=1;i<=n;++i) 24 for(int j=m;j>=a[i];--j) 25 (dp[j]+=dp[j-a[i]])%=10; 26 for(int i=1;i<=n;++i){ 27 memcpy(f,dp,sizeof(dp)); 28 for(int j=a[i];j<=m;++j) f[j]=(f[j]-f[j-a[i]]+10)%10; 29 for(int j=1;j<=m;++j) putchar(f[j]%10+'0'); 30 putchar(' '); 31 } 32 return 0; 33 }