P1507 NASA的食物计划(dp超详解)

    科技2024-08-09  64

    P1507 NASA的食物计划

    题目背景

    NASA(美国航空航天局)因为航天飞机的隔热瓦等其他安全技术问题一直大伤脑筋,因此在各方压力下终止了航天飞机的历史,但是此类事情会不会在以后发生,谁也无法保证,在遇到这类航天问题时,解决方法也许只能让航天员出仓维修,但是多次的维修会消耗航天员大量的能量,因此NASA便想设计一种食品方案,让体积和承重有限的条件下多装载一些高卡路里的食物.

    题目描述

    航天飞机的体积有限,当然如果载过重的物品,燃料会浪费很多钱,每件食品都有各自的体积、质量以及所含卡路里,在告诉你体积和质量的最大值的情况下,请输出能达到的食品方案所含卡路里的最大值,当然每个食品只能使用一次.

    输入格式

    第一行 两个数 体积最大值(<400)和质量最大值(<400)

    第二行 一个数 食品总数N(<50).

    第三行-第3+N行

    每行三个数 体积(<400) 质量(<400) 所含卡路里(<500)

    输出格式

    一个数 所能达到的最大卡路里(int范围内)

    输入输出样例

    输入 #1

    320 350 4 160 40 120 80 110 240 220 70 310 40 400 220

    输出 #1

    550

    说明/提示 很简单的背包…

    我的思路

    这是一题简单的背包问题,本题核心公式:dp[j][k] = max(dp[j][k], dp[j-t[i]][k-z[i]] + l[i]); , 下标 j, k表示在这个j体积和k质量下的最大卡路里,当需要选取时,j - t[i],k - z[i], 下标分别减去该食物的体积和质量并且加上卡路里。

    for (int i = 1; i <= n; i++) for (int j = tj; j >= t[i]; j--) for (int k = zl; k >= z[i]; k--) dp[j][k] = max(dp[j][k], dp[j - t[i]][k - z[i]] + l[i]);

    第一个for表示遍历每个食物, 第二,三个for表示食物的体积和质量,当然,第二,三for的位置可以互换。 至于为什么j的取值范围是tj 到 t[i], 是因为j < t[i]的话不能取该食物。(自行体会)

    AC代码

    #include<bits/stdc++.h> using namespace std; int tj, zl, n, t[401], z[401], l[501], dp[401][401]; int main() { cin >> tj >> zl >> n; for (int i = 1; i <= n; i++) cin >> t[i] >> z[i] >> l[i]; for (int i = 1; i <= n; i++) for (int j = tj; j >= t[i]; j--) for (int k = zl; k >= z[i]; k--) dp[j][k] = max(dp[j][k], dp[j - t[i]][k - z[i]] + l[i]); cout << dp[tj][zl]; return 0; }
    Processed: 0.013, SQL: 8