bzoj2287 POJ Challenge 消失之物(背包)

2287: 【POJ Challenge】消失之物

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 735  Solved: 413
[Submit][Status][Discuss]

Description

ftiasch 有 N 个物品, 体积分别是 W1, W2, ..., WN。 由于她的疏忽, 第 i 个物品丢失了。 “要使用剩下的 N - 1 物品装满容积为 x 的背包,有几种方法呢?” -- 这是经典的问题了。她把答案记为 Count(i, x) ,想要得到所有1 <= i <= N, 1 <= x <= M的 Count(i, x) 表格。

Input

第1行:两个整数 N (1 ≤ N ≤ 2 × 103) 和 M (1 ≤ M ≤ 2 × 103),物品的数量和最大的容积。

第2行: N 个整数 W1, W2, ..., WN, 物品的体积。

Output

一个 N × M 的矩阵, Count(i, x)的末位数字。

 

 

第一反应是跑前缀背包和后缀背包,但是发现是$n^3$的orz;

实际计算count数组时可以用FFT优化,复杂度$O(n^2·logn)$;

 

正解:(来自http://hzwer.com/2446.html)

递推求count时,分三种情况讨论:

  1、$count[i][0]=1$;

  2、$j<w[i]$时,不会用到第$i$个物品,因此$count[i][j]=dp[n][j]$;

  3、$j>=w[i]$时,注意到使用第$i$个物品填满背包等价于不用第$i$个物品填充$m-w[i]$的体积;

     因此$count[i][j]=dp[n][j]-count[i][j-w[i]]$;

复杂度$O(n^2)$;

AC GET☆DAZE

 

↓代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #include<map>
10 #define ll long long
11 using namespace std;
12 int dp[2039][2039],wei[2039],con[2039][2039];
13 int main()
14 {
15     int n,m,a,b,c;
16     scanf("%d%d",&n,&m);
17     for(a=1;a<=n;a++)
18     {
19         scanf("%d",&wei[a]);
20     }
21     dp[0][0]=1;
22     for(a=1;a<=n;a++)
23     {
24         for(b=0;b<=m;b++)
25         {
26             if(b>=wei[a])
27             {
28                 dp[a][b]+=dp[a-1][b-wei[a]];
29             }
30             dp[a][b]+=dp[a-1][b];
31             dp[a][b]%=10;
32         }
33     }
34     for(a=1;a<=n;a++)
35     {
36         con[a][0]=1;
37         for(b=1;b<wei[a];b++)
38         {
39             con[a][b]=dp[n][b];
40         }
41         while(b<=m)
42         {
43             con[a][b]=(dp[n][b]-con[a][b-wei[a]]+10)%10;
44             b++;
45         }
46     }
47     for(a=1;a<=n;a++)
48     {
49         for(b=1;b<=m;b++)
50         {
51             printf("%d",con[a][b]);
52         }
53         cout<<endl;
54     }
55     return 0;
56 }
bzoj2287
散りぬべき 時知りてこそ 世の中の 花も花なれ 人も人なれ
原文地址:https://www.cnblogs.com/Sinogi/p/7446116.html