退背包(好像是这么叫的)
(f[j])是正常的01背包统计方案数,(g[i][j])是删去第i个物品后的01背包统计方案数
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
inline int rd(){
int ret=0,f=1;char c;
while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
while(isdigit(c))ret=ret*10+c-'0',c=getchar();
return ret*f;
}
#define space() putchar(' ')
#define nextline() putchar('
')
void pot(int x){if(!x)return;pot(x/10);putchar('0'+x%10);}
void out(int x){if(!x)putchar('0');if(x<0)putchar('-'),x=-x;pot(x);}
const int MAXN = 2005;
const int MOD = 10;
inline int mul(int x,int y){return (1ll*x*y)%MOD;}
inline void Mul(int &x,int y){x=mul(x,y);}
inline int sub(int x,int y){return x-y<0?x-y+MOD:x-y;}
inline int add(int x,int y){if(y>=0)return x+y>MOD?x+y-MOD:x+y;else return sub(x,-y);}
inline void Add(int &x,int y){x=add(x,y);}
int n,m;
int v[MAXN];
int f[MAXN],g[MAXN][MAXN];
int main(){
n=rd();m=rd();
for(int i=1;i<=n;i++)v[i]=rd();
f[0]=1;
for(int i=1;i<=n;i++){
for(int j=m;j>=v[i];j--){
(f[j]+=f[j-v[i]])%=MOD;
}
}
for(int i=1;i<=n;i++){
g[i][0]=1;
for(int j=1;j<=m;j++){
if(j<v[i]) g[i][j]=f[j];
else g[i][j]=(f[j]-g[i][j-v[i]]+MOD)%MOD;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
out(g[i][j]);
}
nextline();
}
return 0;
}