TaoTao要吃鸡 (01背包)

TaoTao要吃鸡

题目描述


Taotao的电脑带不动绝地求生,所以taotao只能去玩pc版的荒野行动了,
和绝地求生一样,游戏人物本身可以携带一定重量m的物品,装备背包
之后可以多携带h(h为0代表没有装备背包)重量的东西。玩了几天
taotao发现了一个BUG,当装备背包之后,如果可携带重量没有满,就
可以拿一个任意重的东西。(解释看样例)有一天taotao空降到了一个
奇怪的岛上,岛上有n件装备,每个装备都有重量Wi和威力值Vi,但taotao
不认识这些装备,所以他来求助你,挑选威力最大的装备,帮助他吃鸡。

输入描述:

本题有多组输入(小于10),当n=0时结束输入。
第一行输入n,m,h。n,m,h为整数,并且0<=n,m,h<=100,
接下来n行,每行输入第i个物品的物品的重量Wi和威力值Vi。0<=Wi,Vi<=100.

输出描述:

输出最大威力值,每组输出一行。
示例1

输入

3 3 3
2 3
3 2
2 3
0

输出

8

说明

可携带的总重量为6,当拿了前两件装备,此时容量为5/6,还可以再拿第三件物品。


思路:这道题是01背包的变形,根据题意背包总空间为m+h,当h为0时直接01背包解决;当h不为0时,应该让背包空间为m+h-1,然后01背包暴力跑一遍所有n-1件物品再加另一件物品价值找最大值......


 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<map>
 7 #include<set>
 8 #include<vector>
 9 #include<sstream>
10 using namespace std;
11 #define ll long long
12 const int inf=99999999;
13 const int mod=1e9+7;
14 const int maxn=200+10;
15 int dp[maxn][maxn];
16 int value[maxn];
17 int capacity[maxn];
18 int main()
19 {
20     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
21     int n,m,h;
22     while(cin>>n)
23     {
24         if(!n)
25             return 0;
26         memset(dp,0,sizeof(dp));
27         cin>>m>>h;
28         m=m+h;//计算总空间 
29         for(int i=1;i<=n;i++)
30             cin>>capacity[i]>>value[i];//输入体积价值 
31         if(!h)//如果h为0,直接01背包问题 
32         {
33             for(int i=1;i<=n;i++)
34             {
35                 for(int j=0;j<=m;j++)//h为0时m为全部体积 
36                 {
37                     if(j<capacity[i])
38                         dp[i][j]=dp[i-1][j];
39                     else
40                     {
41                         if(dp[i-1][j]>dp[i-1][j-capacity[i]]+value[i])
42                             dp[i][j]=dp[i-1][j];
43                         else
44                             dp[i][j]=dp[i-1][j-capacity[i]]+value[i];
45                     }
46                 }
47             }
48             cout<<dp[n][m]<<endl;
49             continue;
50         }
51         int maxx=-1;
52         m--;//空间减少一,最后多放一件物品 
53         for(int k=1;k<=n;k++)
54         {
55             swap(capacity[k],capacity[1]);//把当前第k件物品换到第一件 
56             swap(value[k],value[1]);
57             for(int i=2;i<=n;i++)//在计算01背包时忽略第一件物品 
58             {
59                 for(int j=0;j<=m;j++)
60                 {
61                     if(j<capacity[i])
62                         dp[i][j]=dp[i-1][j];
63                     else
64                     {
65                         if(dp[i-1][j]>dp[i-1][j-capacity[i]]+value[i])
66                             dp[i][j]=dp[i-1][j];
67                         else
68                             dp[i][j]=dp[i-1][j-capacity[i]]+value[i];
69                     }
70                 }
71             }
72             maxx=max(maxx,dp[n][m]+value[1]);//暴力跑一遍所有物品找最大值 
73             swap(capacity[k],capacity[1]);//注意要换回去 
74             swap(value[k],value[1]);
75         }
76         cout<<maxx<<endl;
77     }
78     return 0;
79 }
 
大佬见笑,,
原文地址:https://www.cnblogs.com/xwl3109377858/p/10939700.html