1. 程式人生 > 實用技巧 >NASA的食物計劃--c++題解

NASA的食物計劃--c++題解

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 22

輸出樣例 1

550

來源

YCOJ(A) http://127.0.0.1

這道看上去與01揹包簡直一模一樣,但如果仔細看的話,會發現它有體積和質量2個限制,其代價也是這2項。所以我們不妨大膽假設:

dp[i][j]表示在體積限制為i,重量限制為j時所獲得的最大卡路里數

我們已經知道了01揹包的寫法:

for(int i=1;i<=n;i++)
        for(int j=m;j>=c[i];j--)
            dp[j]=max(dp[j],dp[j-c[i]]+w[i]);

而此題有2種限制,所以可以大膽加一層迴圈:

for(int i=1;i<=n;i++)
        
for(int j=V;j>=v[i];j--) for(int k=m;k>=c[i];k--)

那麼dp[i][j]得知該怎麼表示呢?

其實跟01揹包的思路一樣,只不過加了1個重量/體積,所以核心程式碼如下:

for(int i=1;i<=n;i++)
        for(int j=V;j>=v[i];j--)
            for(int k=m;k>=c[i];k--)    
                dp[j][k]=max(dp[j][k],dp[j-v[i]][k-c[i]]+w[i]);

下標分別為體積和重量

完整程式碼如下:

#include<bits/stdc++.h>
using namespace std;
int n,m,c[1000010],w[1000010];
int dp[1010][1010],V,v[1000010];

int main()
{
    cin>>V>>m>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>v[i]>>c[i]>>w[i];
    }
    for(int i=1;i<=n;i++)
        for(int j=V;j>=v[i];j--)
            for(int k=m;k>=c[i];k--)    
                dp[j][k]=max(dp[j][k],dp[j-v[i]][k-c[i]]+w[i]);
    cout<<dp[V][m];
    return 0;
}