[bzoj2287] 【POJ Challenge】消失之物
阿新 • • 發佈:2018-11-27
題目描述
ftiasch 有 N 個物品, 體積分別是 W1, W2, …, WN。 由於她的疏忽, 第 i 個物品丟失了。 “要使用剩下的 N – 1 物品裝滿容積為 x 的揹包,有幾種方法呢?” — 這是經典的問題了。她把答案記為 Count(i, x) ,想要得到所有1 <= i <= N, 1 <= x <= M的 Count(i, x) 表格。
輸入輸出格式
輸入格式:
第1行:兩個整數 N (1 ≤ N ≤ 2 × 10^3)N(1≤N≤2×103) 和 M (1 ≤ M ≤ 2 × 10^3)M(1≤M≤2×103),物品的數量和最大的容積。
第2行: N 個整數 W1, W2, …, WN, 物品的體積。
輸出格式:
一個 N × M 的矩陣, Count(i, x)的末位數字。
輸入輸出樣例
輸入樣例#1:
3 2
1 1 2
輸出樣例#1:
11
11
21
說明
如果物品3丟失的話,只有一種方法裝滿容量是2的揹包,即選擇物品1和物品2。
此為luogu題面,bzoj題面(許可權題)
題解
簡單揹包題,每次逆迴圈消去一個物品的影響就行。
#include<bits/stdc++.h> using namespace std; void read(int &x) { x=0;int f=1;char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f; } void print(int x) { if(x<0) x=-x,putchar('-'); if(!x) return ;print(x/10),putchar(x%10+'0'); } void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');} #define maxn 2000 int f[maxn+5],g[maxn+5],n,m,v[maxn+5]; int main() { read(n),read(m); for(int i=1;i<=n;i++) read(v[i]); f[0]=1; for(int i=1;i<=n;i++) for(int j=m-v[i];j>=0;j--) (f[j+v[i]]+=f[j])%=10; for(int i=1;i<=n;i++) { for(int j=0;j<=m;j++) g[j]=f[j]; for(int j=v[i];j<=m;j++) g[j]=((g[j]-g[j-v[i]])%10+10)%10; for(int j=1;j<=m;j++) putchar(g[j]+'0');puts(""); } return 0; }