蓝桥杯-最大价值-解析

题目描述

一名种菜的农民伯伯。需要在给定的时间内完成种菜,现有m种不同的蔬菜提供给农民伯伯选择,且每种蔬菜种植花费的时间不同,每种蔬菜成熟后售卖的价值也不同。

要求:

1.在限定的总时间内进行蔬菜种植,并且种植蔬菜的种类不能超出限制的数量;

2.选择最优的种植方案使得蔬菜成熟后售卖的总价值最大(可选择不同的蔬菜种植)。

例如:

给定的总时间限制为55,种植蔬菜的种类限制为3;

3种蔬菜,种菜的花费时间及售卖价格分别为:第一种21和9,第二种20和2,第三种30和21。

最优的种植方案是选择种植第一种和第三种,两种蔬菜种植总时间30+21,未超过总时间限制55。所种植蔬菜为两种,也未超过种类限制的3种。最大总价值为9+21=30,这个方案是最优的。

输入格式

第一行输入两个正整数t(1<=t<=600)和m(1<=m<=50),用一个空格隔开,t代表种菜总时间限制,m代表最多可种植蔬菜种类的限制;

接下来的m行每行输入两个正整数t1(1<t1<101)和p(1<p<101)且用一个空格隔开,t1表示每种蔬菜种植需要花费的时间,p表示对应蔬菜成熟后售卖的价值。

输出格式

输出一个正整数,表示选择最优的种植方案后,蔬菜成熟后售卖的最大总价值。

输入数据 1

53 3
21 9
20 2
30 21

Copy

输出数据 1

30

 

解析

这是一个典型的背包问题(0/1背包问题),我们可以用动态规划来解决这个问题。我们要在给定的时间限制内选择不同的蔬菜,以最大化总的售卖价值。

以下是解决方案的C++代码实现:

#include <iostream>  
#include <vector>  
#include <algorithm>  

using namespace std;  

struct Vegetable {  
    int time;   // 种植需要的时间  
    int value;  // 成熟后的价值  
};  

int main() {  
    int t, m; // t为总时间限制,m为蔬菜种类限制  
    cin >> t >> m;  

    vector<Vegetable> vegetables(m);  
    
    // 读取蔬菜的信息  
    for (int i = 0; i < m; ++i) {  
        cin >> vegetables[i].time >> vegetables[i].value;  
    }  
    
    // dp[i][j]表示在时间限制为j,选择最多前i种蔬菜的最大价值  
    vector<vector<int>> dp(m + 1, vector<int>(t + 1, 0));  
    
    // 动态规划  
    for (int i = 1; i <= m; ++i) {  
        for (int j = 0; j <= t; ++j) {  
            // 不选择当前蔬菜  
            dp[i][j] = dp[i - 1][j];   
            
            // 选择当前蔬菜  
            if (j >= vegetables[i - 1].time) {  
                dp[i][j] = max(dp[i][j], dp[i - 1][j - vegetables[i - 1].time] + vegetables[i - 1].value);  
            }  
        }  
    }  

    // 查找最大价值,考虑最多种类限制  
    int maxValue = 0;  
    for (int j = 0; j <= t; ++j) {  
        maxValue = max(maxValue, dp[m][j]);  
    }  

    cout << maxValue << endl;  

    return 0;  
}

代码说明:

  1. 输入处理:首先读取总时间限制 t 和蔬菜种类限制 m,然后推入每种蔬菜的种植时间和价值到一个结构体数组 vegetables

  2. 动态规划数组定义:创建 dp数组,dp[i][j]表示考虑了前 i 种蔬菜,并在时间限制为 j 的情况下所能得到的最大价值。

  3. 动态规划填表

    • 对每种蔬菜,我们先不选择它,然后计算选择这个蔬菜的情况。
    • 如果时间允许(j >= vegetables[i - 1].time),更新 dp[i][j] 的值,选择当前蔬菜或不选择的最大值。
  4. 获取结果:遍历最后一个状态的所有时间限制值,选择其中的最大值作为结果。

  5. 输出:将最大价值输出到标准输出。

注意事项:

  • 代码中的时间复杂度为 O(m * t),对于给定的限制,性能是可以接受的。
  • 确保输入格式正确,按要求输入。

目录

题目描述

        输入格式

        输出格式

        输入数据 1

        输出数据 1

解析        

代码说明:

注意事项:


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值