首页 > 代码库 > BZOJ2287: 【POJ Challenge】消失之物
BZOJ2287: 【POJ Challenge】消失之物
2287: 【POJ Challenge】消失之物
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 254 Solved: 140
[Submit][Status]
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)的末位数字。
Sample Input
3 2
1 1 2
1 1 2
Sample Output
11
11
21
11
21
HINT
如果物品3丢失的话,只有一种方法装满容量是2的背包,即选择物品1和物品2。
Source
题解:
刚开始看见题,这不是前缀后缀随便搞吗,然后开开心心写代码,到了输出的时候忽然发现这不是成了n*m*m的。。。。T_T
无奈看了题解。
背包变种,设n为物品数量,nums[i]为物品的重量,dp1[i][j] 为前i个物品放入容量为j的背包中的方案数目,那么显然有:
dp1[i][j] = sum{dp1[i-1][j-nums[i]]};
那么所有的物品放入容量为j的数目是dp1[n][j];
令dp2[i][j]为除去第i个物品,放入容量为j的背包中的方案数目:
dp2[i][j] = dp1[n][j] - dp2[i][j-nums[i]],表示从选择所有物品装的方案中,筛去包含i物品的方案数
看来我还没有掌握背包的精髓?
代码:
1 #include<cstdio> 2 3 #include<cstdlib> 4 5 #include<cmath> 6 7 #include<cstring> 8 9 #include<algorithm>10 11 #include<iostream>12 13 #include<vector>14 15 #include<map>16 17 #include<set>18 19 #include<queue>20 21 #include<string>22 23 #define inf 100000000024 25 #define maxn 2000+526 27 #define maxm 500+10028 29 #define eps 1e-1030 31 #define ll long long32 33 #define pa pair<int,int>34 35 #define for0(i,n) for(int i=0;i<=(n);i++)36 37 #define for1(i,n) for(int i=1;i<=(n);i++)38 39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)40 41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)42 43 #define mod 100000000744 45 using namespace std;46 47 inline int read()48 49 {50 51 int x=0,f=1;char ch=getchar();52 53 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}54 55 while(ch>=‘0‘&&ch<=‘9‘){x=10*x+ch-‘0‘;ch=getchar();}56 57 return x*f;58 59 }60 int n,m,a[maxn],f[maxn],g[maxn];61 62 int main()63 64 {65 66 freopen("input.txt","r",stdin);67 68 freopen("output.txt","w",stdout);69 70 n=read();m=read();71 for1(i,n)a[i]=read();72 f[0]=1;73 for1(i,n)74 for3(j,m,a[i])(f[j]+=f[j-a[i]])%=10;75 g[0]=1;76 for1(i,n)77 {78 for1(j,m)g[j]=(f[j]-(j>=a[i]?g[j-a[i]]:0)+10)%10;79 for1(j,m)printf("%d",g[j]);80 printf("\n");81 }82 83 return 0;84 85 }
BZOJ2287: 【POJ Challenge】消失之物
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。