前言:这道题实在01背包问题的基础上拓展的,所以如果对背包问题解法还不是很熟悉的话建议先熟悉一下01背包的解法再来研究这答题,这样你会觉得这道题也就那样子,只是多了一个判断是否限购而已。
问题描述
某一年“五一”,刚刚办完签证的小G决定到香港旅游。因为之前一直听说旺角很热闹,所以小G第一站便到了旺角。到了旺角商业街之后,发现这里果然是商业成群。小G在逛街的时候意外发现了在内陆很难买到的一件奢侈品,喜欢货比三家的他用一个上午的时间走访了几乎所有的商店,发现一共有n家店有卖该奢侈品。但令人不解的是,其中有部分出售该奢侈品的国外商店不允许顾客购买多件奢侈品!
假设每一家出售该奢侈品的商店拥有无数件该奢侈品,现在小G身上总额一共为W。请你帮他决策,使得他最后能得到的价值期望值最大。
输入要求
输入包含多组测试数据。每一组数据第一行输入两个正整数:n,W(n<=100,W<=100000)分别表示有n家店和小G身上的总金额。下面n行每一行包含三个整数:f,w,v(t=0或者1,1<=w、v<=1000,0000)。其中,f=0表示该店仅允许小G买一件该奢侈品,f=1表示允许购买多件;整数w、v分别表示小G在该店购买一件奢侈品的代价以及其价值期望。
输出要求
对于每一组测试数据,输出小G在额度W内所能获得的最大价值期望,占一行。
样例输入
2 10
0 2 5
1 1 2
5 20
1 21 10
0 5 11
1 7 3
0 4 7
1 1 2
样例输出
21
41
题解:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(true){
int n = sc.nextInt();
int W = sc.nextInt();
int[] dp = new int[W+1];
for(int i=0;i<n;i++){
int flag = sc.nextInt(); // 该店是否限购
int w = sc.nextInt();
int v = sc.nextInt();
if(flag==0){ //该店限购
for(int j=W;j>=w;j--){ // 从尾部开始判断,防止价值期望叠加
dp[j] = max(dp[j],dp[j-w]+v);
}
} else { // 不限购
for(int j=w;j<=W;j++){ // 从起点开始,叠加价值期望
dp[j] = max(dp[j],dp[j-w]+v);
}
}
}
System.out.println(dp[W]);
}
}
private static int max(int a, int b) {
if(a>b)
return a;
return b;
}
}
题目来源:http://acm.gdufe.edu.cn/Problem/read/id/1162