背包dp

多重背包转01背包

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <vector>
 5 using namespace std;
 6 
 7 const int MAXN=1010;
 8 
 9 int n;
10 struct Node
11 {
12     int w,v;   //价钱、价值
13     int id;   //玩偶编号
14 }p[MAXN*100];
15 int dp1[MAXN*100][MAXN];   //正向考虑到第i个物品,花掉j钱时获得的价值为dp1[]
16 int dp2[MAXN*100][MAXN];   //反向考虑到第i个物品,花掉j钱时获得的价值为dp2[]
17 
18 int main()
19 {
20     scanf("%d",&n);
21     int cnt=0;   //二进制拆分后的玩偶个数
22     for (int i=1;i<=n;i++)
23     {
24         int a,b,c;   //价钱、价值、限购次数
25         scanf("%d%d%d",&a,&b,&c);
26         //对每个玩偶二进制拆分
27         int bit=1;
28         while (c>=bit)
29         {
30             cnt++;
31             p[cnt].w=bit*a;
32             p[cnt].v=bit*b;
33             p[cnt].id=i;
34             c-=bit;
35             bit*=2;
36         }
37         if (c)
38         {
39             cnt++;
40             p[cnt].w=c*a;
41             p[cnt].v=c*b;
42             p[cnt].id=i;
43         }
44     }
45 
46     memset(dp1,0,sizeof(dp1));
47     memset(dp2,0,sizeof(dp2));
48     //正向考虑
49     for (int i=1;i<=cnt;i++)   //枚举每份玩偶
50     {
51         for (int j=0;j<1000;j++) dp1[i][j]=dp1[i-1][j];
52         for (int j=1000;j>=p[i].w;j--)   //枚举所花价钱
53         {
54             dp1[i][j]=max(dp1[i][j],dp1[i-1][j-p[i].w]+p[i].v);
55         }
56     }
57     //反向考虑
58     for (int i=cnt;i>=1;i--)
59     {
60         for (int j=0;j<1000;j++) dp2[i][j]=dp2[i+1][j];
61         for (int j=1000;j>=p[i].w;j--)
62         {
63             dp2[i][j]=max(dp2[i][j],dp2[i+1][j-p[i].w]+p[i].v);
64         }
65     }
66 
67     int q;
68     scanf("%d",&q);
69     while (q--)
70     {
71         int d,e;
72         scanf("%d%d",&d,&e);
73         d++;
74         int ans=0;
75         int l=0,r=0;
76         while (p[l+1].id<d && l<n) l++;
77         r=l;
78         while (p[r].id<=d && r<n) r++;
79         for (int j=0;j<=e;j++)   //枚举分给左边多少钱数
80         {
81             ans=max(ans,dp1[l][j]+dp2[r][e-j]);   //左右合并考虑
82         }
83         printf("%d\n",ans);
84     }
85 
86     return 0;
87 }
posted @ 2021-12-05 09:32  Hell0er  阅读(28)  评论(0编辑  收藏  举报