Consumer
Consumer
題意:
n個游戲機,有w錢
每個游戲機上有游戲,每個游戲有價格和娛樂值,游戲機有價格,沒有娛樂值,玩游戲必須要用對應(yīng)的游戲機,問娛樂值最大是多少
題解:
有依賴關(guān)系的背包問題
對于一個游戲機,游戲機本身沒有娛樂值,但是上面的游戲有娛樂值,所以我們可以選擇不要這個游戲機,或者要游戲機以及里面的物品,我們要求出選擇這個箱子以及其中的物品在各個費用下所能取的最大價值
dp[i][j]就表示前i個游戲機,花費在j以內(nèi)的最大價值
如果j<游戲機價格,說明連游戲機都買不起,更別想游戲,所以dp[i][j]=-1;
如果j>游戲機價格val,j中val用于買游戲機,此時的狀態(tài)等于不選第i個游戲機,有j-val錢的狀態(tài)dp[i][j]=dp[i-1][j-val]
現(xiàn)在的dp[][]表示選了游戲機后的狀態(tài),直接對游戲機中的游戲進行01背包求各個費用下的最大價值
if(dp[i][j-cost]!=-1)dp[i][j] = max(dp[i][j], dp[i][j - cost] + val);經(jīng)過上述操作,我們得到了選擇當(dāng)前游戲機i 的的情況下,各個費用下的最大價值
然后我們?nèi)ズ筒贿x這個游戲機的情況下,各個費用下的最大價值取最大值,這樣就得到挑選過游戲機i后得到的各個費用的最大值
不選游戲機就是dp[i-1][…]
代碼:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> //#define LOCAL = 1; using namespace std; typedef long long ll; const int Max = 1e5 + 10;int n, m; ll dp[55][Max];int main() {while (scanf("%d%d", &n, &m) != EOF){memset(dp, 0, sizeof(dp)); //初始化for(int i = 1 ;i <= n;i ++){int box, num;scanf("%d%d", &box, &num);for (int j = 0;j < box; j++) //總費用小于box,無法買任何物品dp[i][j] = -1;for (int j = box;j <= m; j++) //由前一個狀態(tài)j-box,選擇了當(dāng)前的游戲機后轉(zhuǎn)移而來dp[i][j] = dp[i - 1][j - box];//上述表示選擇了當(dāng)前的游戲機后的價值(沒有和不選進行比較)for(int k = 0 ;k < num ; k ++) //由01背包從選擇了箱子的狀態(tài)轉(zhuǎn)移到其余狀態(tài){int cost;ll val;scanf("%d%lld", &cost, &val);for(int j = m ; j >= cost ;j --){if(dp[i][j-cost] != -1){dp[i][j] = max(dp[i][j], dp[i][j - cost] + val);}}}for (int j = 0;j <= m;j++) //和不選擇此盒子作比較dp[i][j] = max(dp[i][j], dp[i - 1][j]);}printf("%lld\n", dp[n][m]);}return 0; }總結(jié)
- 上一篇: 鸡爪莲的功效与作用、禁忌和食用方法
- 下一篇: 郊区春游题解