zoukankan      html  css  js  c++  java
  • 考研机试 66.点菜问题

    时间:2021/03/09

    一.题目描述

    北大网络实验室经常有活动需要叫外卖,但是每次叫外卖的报销经费的总额最大为C元,有N种菜可以点,经过长时间的点菜,网络实验室对于每种菜i都有一个量化的评价分数(表示这个菜可口程度),为Vi,每种菜的价格为Pi, 问如何选择各种菜,使得在报销额度范围内能使点到的菜的总评价分数最大。     注意:由于需要营养多样化,每种菜只能点一次。

    输入描述

    输入的第一行有两个整数C(1 <= C <= 1000)和N(1 <= N <= 100),C代表总共能够报销的额度,N>代表能点菜的数目。
    接下来的N行每行包括两个在1到100之间(包括1和100)的的整数,分别表示菜的>价格和菜的评价分数

    输出描述

    输出只包括一行,这一行只包含一个整数,表示在报销额度范围内,所点的菜得到的最大评价分数。

    题目链接

    https://www.nowcoder.com/practice/b44f5be34a9143aa84c478d79401e22a?

    tpId=40&tqId=21397&rp=1&ru=%2Fta%2Fkaoyan&qru=%2Fta%2Fkaoyan%2Fquestion-ranking&tab=answerKey

    二.算法

    题解

    本题是在求给定金额下的最优值问题,由于每种菜只能购买一次,所以这是一个典型的0-1背包问题,也就是一个选与不选的问题。对于0-1背包问题的求解思路:若背包的最大容量记为c,物品有n种,每种物品都有自己的重量和价值,则我们建立一个n+1行,c+1列的数组dp,建立完数组后,我们令第零行和第零列的值为0,然后开始从第一行、第一列遍历整个dp数组,若当前容量j(也就是列数)大于等于该行所代表物体的重量,则dp[i][j]=max(dp[i-1][j],dp[i-1][j-该行多代表物体的重量] + 该行所代表物体的价值),即取选与不选中较大的那一个;若当前容量小于该行所代表物体的重量,则dp[i][j]=dp[i-1][j]。一定要注意下标,最好都从1开始。 

    重点

    0-1背包问题

    代码

    import java.util.Scanner;
    
    public class Main{
        
        public static void main(String[] args){
            //读取输入
            Scanner in = new Scanner(System.in);
            while(in.hasNext()){
                int c = in.nextInt();
                int n = in.nextInt();
                int[] p = new int[n];
                int[] v = new int[n];
                for(int i = 0; i < n; i++){
                    p[i] = in.nextInt();
                    v[i] = in.nextInt();
                }
                //求解点菜问题(根据0-1背包问题的思路)
                int[][] dp = new int[n + 1][c + 1];
                for(int i = 0; i <= c; i++){
                    dp[0][i] = 0;
                }
                for(int i = 0; i <= n; i++){
                    dp[i][0] = 0;
                }
                for(int i = 1; i <= n; i++){
                    for(int j = 1; j <= c; j++){
                        if(j >= p[i - 1]){
                            dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - p[i - 1]] + v[i - 1]);
                        }else{
                            dp[i][j] = dp[i - 1][j];
                        }
                    }
                }
                System.out.println(dp[n][c]);
            }
            //System.out.println(dp(0, n - 1));
        }
        
        //使用递归求解动态规划问题
    //     public static int dp(int money, int index){
    //         if(money > c){
    //             return 0;
    //         }
    //         if(index < 0){
    //             return 0;
    //         }else{
    //             return Math.max(dp(money, index - 1), dp(money + p[index], index - 1) + v[index]);
    //         }
    //     }
    }
    努力,向上,自律
  • 相关阅读:
    88. Merge Sorted Array【leetcode】算法,java将两个有序数组合并到一个数组中
    70. Climbing Stairs【leetcode】递归,动态规划,java,算法
    136. Single Number【LeetCode】异或运算符,算法,java
    605. Can Place Flowers种花问题【leetcode】
    175. Combine Two Tables【LeetCode】-LEFT JON 和RIGHT JOIN,两张表关联查询-java -sql入门
    67. Add Binary【LeetCode】
    4.1 yaml配置注入
    2.1容器功能-组件添加
    1.2自动配置
    json乱码问题全配置
  • 原文地址:https://www.cnblogs.com/machi12/p/14505704.html
Copyright © 2011-2022 走看看