[BZOJ] 2287: 【POJ Challenge】消失之物

退背包(好像是这么叫的)
\(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('\n')
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;
}
posted @ 2018-10-22 09:25  GhostCai  阅读(75)  评论(0编辑  收藏  举报