• 30. 有一个人前来买瓜


    目录

    题目

    Input

    Output

    思路

    C++完整代码(含注释)


    题目

    军训这么累,当然要吃瓜啦。

    有一个小军前来买瓜。

    众所周知,YHW水果摊里的西瓜的瓜皮子和瓜粒子都是金粒子做的。小军当然想获得尽可能多的金粒子。

    一共有n个瓜,每个瓜有重量w,成熟度v,金粒子数量g。

    虽然小军的钱是无限的,但他的电动车载重是有限的,因此他不能买总重量超过W的瓜。

    "我开水果摊的,能卖给你生瓜蛋子? ——YHW

    因此,当小军买的瓜的总成熟度小于V时,YHW并不会把瓜卖给他。

    具体的:水果摊一共有n个瓜,每个瓜有重量w,成熟度v,金粒子数量g。一共有q次询问,每次询问给出两个值W、V,小军要选取n个瓜的子集,使总重量 Σw≤W,总成熟度Σv≥V,求 Σg
    的最大值。

    Input

    第一行输入两个整数,q(1≤n≤100,1≤q≤100),代表瓜的数量和询问数量。

    接下来n行,每行三个整数,第i行的三个整数为i,vi,gi(1≤wi,vi,gi≤100),分别代表第i个瓜的重量,成熟度和价值。

    接下来q行,输入两个整数,V(1≤W,V≤500),代表一组询问。

    Output

    输出一共有q行,每行一个整数,分别代表每组询问的最大金粒子数总和,若无合法的买法则输出-1。


    思路

    本题使用动态规划的思路解决了一个背包问题。通过存储瓜的重量、成熟度和金粒子数的信息,利用一个二维的dp数组来表示状态,通过递推公式来更新状态,然后根据给定的最大重量和最小成熟度处理每组询问,得到最大金粒子数总和。

    步骤如下

    1. 确定dp数组以及下标的含义:

      dp数组是一个二维数组,dp[i][j]表示当前重量为i,成熟度为j时的最大金粒子数总和
    2. 确定递推公式:

      在遍历每个瓜的过程中,对于每个状态dp[j][k],如果当前状态可以转移到状态dp[j + melons[i].weight][min(k + melons[i].maturity, 500)](重量加上当前瓜的重量不超过最大重量500),则更新转移后的状态的金粒子数总和为dp[j][k] + melons[i].gold,并取较大的值
    3. dp数组的初始化:

      dp数组初始化为-1,表示无法达到该状态。
      而dp[0][0]被设置为0,表示初始状态。
    4. 确定遍历顺序:

      遍历瓜的顺序是从0到n-1,即按照输入的顺序遍历瓜的信息。
      对于每个瓜,利用三个嵌套的循环,从重量和成熟度的最大值开始递减遍历,确保在更新dp数组时,可以利用之前计算好的状态。
      这里的遍历顺序是从后往前遍历,以确保之前的状态不被覆盖。
    5. 处理输入输出
      完成动态规划的计算后,开始处理每组询问。读取询问的最大重量W和最小成熟度V,并初始化结果result为-1。
      然后,从重量0到最大重量W,从最小成熟度V到500遍历,将每个状态的最大金粒子数总和与result比较,取较大值。
      最后输出每组询问的最大金粒子数总和result。

    该算法的时间复杂度为O(nW500),其中n为瓜的数量,W为最大重量。


    C++完整代码(含注释)

    提交乐学记得修改!!有查重

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. // 定义瓜的结构体
    6. struct melon {
    7. int weight;
    8. int maturity;
    9. int gold;
    10. };
    11. int main() {
    12. int n, q;
    13. cin >> n >> q;
    14. vector melons(n);
    15. // 读取每个瓜的信息
    16. for (int i = 0; i < n; i++) {
    17. scanf("%d %d %d", &melons[i].weight, &melons[i].maturity, &melons[i].gold);
    18. }
    19. // dp数组,表示状态
    20. vectorlong long>> dp(501, vector<long long>(501, -1));
    21. dp[0][0] = 0;
    22. // 动态规划计算
    23. for (int i = 0; i < n; i++) {
    24. for (int j = 500; j >= 0; j--) {
    25. for (int k = 500; k >= 0; k--) {
    26. // 如果dp[j][k]为有效状态且加上当前瓜的重量不超过最大重量500
    27. if (dp[j][k] >= 0 && j + melons[i].weight <= 500) {
    28. // 更新状态,取金粒子数总和的较大值
    29. dp[j + melons[i].weight][min(k + melons[i].maturity, 500)] = max(dp[j][k] + melons[i].gold, dp[j + melons[i].weight][min(k + melons[i].maturity, 500)]);
    30. }
    31. }
    32. }
    33. }
    34. // 处理每组询问
    35. while (q--) {
    36. int W, V;
    37. scanf("%d %d", &W, &V);
    38. long long result = -1;
    39. // 遍历所有可能的状态,取金粒子数总和的最大值
    40. for (int j = 0; j <= W; j++) {
    41. for (int k = V; k <= 500; k++) {
    42. result = max(result, dp[j][k]);
    43. }
    44. }
    45. // 输出结果
    46. cout << result << endl;
    47. }
    48. return 0;
    49. }

  • 相关阅读:
    数商云SCM供应链协同系统:招标功能亮点|构建数字化采购体系降低汽车零部件成本
    嵌入式学习:使用vscode配置esp32环境(从安装到测试)
    Elasticsearch简介及SpringBoot整合ES实例
    实战:kubeadm方式搭建k8s集群(containerd)-2022.12.5(成功测试-超详细)【荐】
    c# 调用巴斯勒相机 进行图像识别
    多线程学习笔记
    逻辑回归(Logistic Regression)
    32-Docker-常用命令详解-docker start/stop/restart
    C++(11):enable_shared_from_this
    Hive客户端hive与beeline的区别
  • 原文地址:https://blog.csdn.net/m0_74200772/article/details/132731359