Huawei Online Programming Question Series-16-Shopping List

Problem Description:

Problem Description
Problem Description

1. The question involves knowledge points.

  • dynamic programming.

2. Solve it yourself.

  • Merge the data first.
(原始数据)
1000 5
800 2 0
400 5 1
300 5 1
400 3 0
500 2 0

(因为最后结果是需要和重要性进行加权的,所以提前进行加权)
_______________
800 1600 0 
400 2000 1 
300 1500 1 
400 1200 0 
500 1000 0 

(因为购买主物品时候必须购买附属品,所以把附属品加再主物品上)
_______________
(构成动态规划处理数据)
1500 5100 
400 1200 
500 1000 
_______________
2200
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int allMoney = scanner.nextInt();
        int N = scanner.nextInt();
        int [][]intArr = new int[N][3];
        for(int i=0;i<N;i++){
            intArr[i][0] = scanner.nextInt(); // 价格
            intArr[i][1] = intArr[i][0]*scanner.nextInt(); // 价格 *重要度(评估的价值)
            intArr[i][2] = scanner.nextInt(); // 附属属性
        }

        int result = getResult(allMoney,intArr);
        System.out.println(result);
    }

    private static int getResult(int allMoney, int[][] intArr) {
        int N = intArr.length;
//        System.out.println("_______________");
//        Utils.printIntArr2(intArr,N,3);
        // 把附属品的价格和价值合并再主件上
        int [][]intArr_2  = new int[N+1][2];
        int intArr_2Index = 1;
        for (int[] anIntArr : intArr) {
            if (anIntArr[2] != 0) {
                intArr_2[anIntArr[2] - 1][0] = intArr_2[anIntArr[2] - 1][0] + anIntArr[0];
                intArr_2[anIntArr[2] - 1][1] = intArr_2[anIntArr[2] - 1][1] + anIntArr[1];
            } else {
                intArr_2[intArr_2Index][0] = anIntArr[0];
                intArr_2[intArr_2Index][1] = anIntArr[1];
                intArr_2Index++;
            }
        }

        return DP(intArr_2,allMoney,intArr_2Index);
    }
    private static int DP(int[][] intArr, int allMoney,int intArr_2Index) {
//        System.out.println("_______________");
//        Utils.printIntArr2(intArr,intArr_2Index,2);
        // 1 建立数组
        int[][] keyMap = new int[allMoney+1][intArr_2Index];//java会给数组默认为0.所以不用初始化.
        // 2 建立keyMap.
        for(int j=1;j<keyMap.length;j++){
            for(int i=1;i<keyMap[j].length;i++){
                if(j<intArr[i][0]){
                    // 不装
                    keyMap[j][i] = keyMap[j][i];
                }else {
                    //装
                    keyMap[j][i] = Math.max(keyMap[j][i-1],intArr[i][1]+keyMap[j-intArr[i][0]][i-1]);
                }
            }
        }
//        System.out.println("_______________");
//        Utils.printIntArr2(keyMap,allMoney+1,intArr_2Index);
        return keyMap[keyMap.length-1][keyMap[0].length-1];
    }
}

3. Quality answers.

链接:https://www.nowcoder.com/questionTerminal/f9c6f980eeec43ef85be20755ddbeaf4
来源:牛客网

import java.util.Scanner;

public class Main{

    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int sum_money = 0;
        int num = 0;           
        sum_money=sc.nextInt();
        num=sc.nextInt();
        int price[]=new int[num+1];
        int val[]=new int[num+1];
        int[] q = new int[num+1];
        for (int i = 1; i <= num; i++) {
            price[i]=sc.nextInt();
            val[i]=sc.nextInt()*price[i];
            q[i]=sc.nextInt();
        }
        int[][] dp=new int[num+1][sum_money+1];
/*
* 初始值java默认赋值为0,其中dp[0][0...sum_money]为0,从dp[1][0...sum_money]
  计算第1行,代表第一件物品
dp[i][sum_money] : 前i个物体放入容量为sum_money的背包的最大价值;
dp[i-1][sum_money] : 前i-1个物体放入容量为sum_money的背包的最大价值;
dp[i-1][sum_money-price[i]] : 前i-1个物体放入容量为sum_money-price[i]的背包的最大价值;
dp[i][sum_money]=Math.max{dp[i-1][sum_money-price[i]]+val[i] , dp[i-1][sum_money]}
*/
        for (int i = 1; i <=num; i++) {
            for (int j = 1; j <= sum_money; j++) {
                if(q[i]==0)
                {
                    if(price[i]<=j)
                        dp[i][j]=Math.max(dp[i-1][j], dp[i-1][j-price[i]]+val[i]);
                }
                if(q[i]>0)
                {
                    if(price[i]+price[q[i]]<=j)
                        dp[i][j]=Math.max(dp[i-1][j], dp[i-1][j-price[i]-price[q[i]]]+val[i]+val[q[i]]);
                }
            }

        }
        System.out.println(dp[num][sum_money]);
    }
}

4. Summary of this question.

This question uses dynamic programming. The idea of ​​dynamic programming is to record the best quality at different times in the form of an array. When calculating later, the previous value is directly called without recalculation.
The accuracy of dynamic programming depends on the data and structure. The array of ((capacity+1)*(data amount+1)) must pay attention to whether the data amount here starts from 0 or 1. If it starts from 1, it is not necessary to +1.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325966838&siteId=291194637