ACM_01背包(修改版)

背包2

Time Limit: 2000/1000ms (Java/Others)

Problem Description:

有n个重量和价值分别为Wi,Vi的物品,现从这些物品中挑选出总量刚好为 W 的物品,求所有方案中价值总和的最大值。

Input:

输入包含多组测试用例,每一例的开头为两位整数 n、W(1<=n<=10000,1<=W<=1000),接下来有 n 行,每一行有两位整数 Wi、Vi(1<=Wi<=10000,1<=Vi<=100)。

Output:

输出为一行,即所有方案中价值总和的最大值。若不存在刚好填满的情况,输出“-1”。

Sample Input:

3 4
1 2
2 5
2 1
3 4
1 2
2 5
5 1

Sample Output:

6
-1
解题思路:这是01背包的修改版。结合题目,若不存在刚好填满的情况为-1,我们可以把dp数组元素全部初始化为-1,这样直接输出dp[W]就可以知道从这些物品中挑选出总量刚好为W时,其价值总和是不是也达到最大,并且不是-1时才可以使用状态转移方程。
AC代码:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int w[10005],v[10005],dp[10005];
 4 int main()
 5 {
 6     int n,W;
 7     while(cin>>n>>W){
 8         memset(dp,-1,sizeof(dp)); //全部初始化为-1
 9         dp[0]=0;//默认初始化为0
10         for(int i=0;i<n;++i)
11             cin>>w[i]>>v[i];
12         for(int i=0;i<n;++i){
13             for(int j=W;j>=w[i];--j){
14                 if(dp[j-w[i]]!=-1)  //如果不是-1的才可以进行比较取舍
15                     dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
16             }
17         }
18         cout<<dp[W]<<endl;  //直接输出总量为W时的价值
19     }
20     return 0;
21 }

猜你喜欢

转载自www.cnblogs.com/acgoto/p/8999316.html