P4141 消失之物(背包)

传送门

太珂怕了……为什么还有大佬用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('\n');
31     }
32     return 0;
33 }

猜你喜欢

转载自www.cnblogs.com/bztMinamoto/p/9786526.html
今日推荐