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]);
    //         }
    //     }
    }
    努力,向上,自律
  • 相关阅读:
    将Nginx添加到windows服务中
    springboot使用redis管理session
    GIT常用命令
    阻止360、谷歌浏览器表单自动填充
    谈谈对Spring IOC的理解
    同一个Nginx服务器同一端口配置多个代理服务
    LeetCode 653. Two Sum IV
    109. Convert Sorted List to Binary Search Tree(根据有序链表构造平衡的二叉查找树)
    108. Convert Sorted Array to Binary Search Tree(从有序数组中构造平衡的BST)
    LeetCode 236. Lowest Common Ancestor of a Binary Tree(二叉树求两点LCA)
  • 原文地址:https://www.cnblogs.com/machi12/p/14505704.html
Copyright © 2011-2022 走看看