- 地址https://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4
代码
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * @author [email protected] * @version V2.1 * @date 2019/8/14 11:10 * @since 2.1.0 */ public class Main { public static void main(String[] args) { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); try { String[] input = bufferedReader.readLine().split("\\s+"); int money = Integer.valueOf(input[0]); int itemNum = Integer.valueOf(input[1]); // 价格 int[] prices = new int[itemNum]; // 价值 = 价格*重要度 int[] values = new int[itemNum]; // 类型。=0表示主件,>0表示附件,数值为所属的主件,编号从1开始。 int[] types = new int[itemNum]; for (int i = 0; i < itemNum; i++) { input = bufferedReader.readLine().split("\\s+"); prices[i] = Integer.valueOf(input[0]); values[i] = prices[i] * Integer.valueOf(input[1]); types[i] = Integer.valueOf(input[2]); } // 1.对每一个主件及其所属附件进行01背包。将问题转为分组问题。 int[][] dps = new int[itemNum][money+1]; for (int i = 0; i < itemNum; i++) { // 当类型为主件时,对当前主件及其所属附件进行01背包,注意必须选择主件。 if (types[i] == 0) { // 记录,对当前主件进行01背包 int masterNo = i + 1; // 为所有背包加入主件 for (int sum=money; sum >= prices[i]; sum--) { dps[i][sum] = values[i]; } for (int j = 0; j < itemNum; j++) { // 类型为附件,主件已经提前加入 if (types[j] == masterNo) { // 状态转移方程, 注意这里使用一维数组优化, 所以为倒序。 for(int sum=money; sum>= (prices[j]+ prices[i]); sum--) { // F[v] = MAX(F(v), F(v-C) + W) dps[i][sum] = Math.max(dps[i][sum], dps[i][sum - prices[j]] + values[j]); } } } } } // 2. 进行分组背包 int[] dp = new int[money+1]; // 遍历分组 for(int i=0; i<itemNum; i++) { // 只需要主件分组 if (types[i] == 0) { // 遍历容量, 因为使用一维数组优化,采用倒序遍历 for (int v = money; v >= 0; v--) { // 遍历组件中的每件物品 for (int k = 0; k <= money; k++) { if (v-k >= 0) { dp[v] = Math.max(dp[v], dp[v - k] + dps[i][k]); } } } } } System.out.println(dp[money]); } catch (IOException ex) { ex.printStackTrace(); } } }
依赖背包问题
猜你喜欢
转载自www.cnblogs.com/bosslv/p/11388925.html
今日推荐
周排行