动规-退背包(【POJ Challenge】消失之物,BZOJ2287)
f[i] 不删除任何物品,达到体积 i 的方案数。
T[i][j] 删除 i 号物品,达到体积 j 的方案数。
T[i][j] = f[j]-T[i][j-W[i]] (j >= W[i])
T[i][j] = f[j] (j < W[i])
1 #include <stdio.h> 2 3 const int _N = 2050; 4 5 int W[_N], T[_N][_N], f[_N]; 6 7 int main() 8 { 9 int N, M, i, j; 10 scanf("%d%d", &N, &M); 11 for (i = 1; i <= N; ++i) 12 scanf("%d", &W[i]); 13 f[0] = 1; 14 for (i = 1; i <= N; ++i) 15 for (j = M; j >= W[i]; --j) 16 f[j] = (f[j]+f[j-W[i]])%10; 17 for (i = 1; i <= N; ++i) { 18 T[i][0] = 1; 19 for (j = 1; j <= M; ++j) { 20 if (j >= W[i]) T[i][j] = (f[j]-T[i][j-W[i]])%10; 21 else T[i][j] = f[j]; 22 printf("%d", (T[i][j]+10)%10); 23 } 24 printf("\n"); 25 } 26 return 0; 27 }