HDU2159_二維完全背包問題
阿新 • • 發佈:2018-07-21
res sha main space sizeof 表示 ring bsp csharp
HDU2159_二維完全背包問題
輸入有:經驗,忍耐度,怪物種數,限制殺怪數 每一種怪物對應獲得的經驗值和消耗的耐久值
輸出:剩下的最大忍耐度
限制:忍耐度,殺怪個數
在這裏把忍耐度看成背包的容量,殺怪個數限制作為第二維
dp[i][j]表示在背包容量為i的時候,放了j件物品所產生的價值
接下來就是循環問題
先遍歷每一個物品(怪物) i
然後遍歷體積(耐久值)正序遍歷——完全背包 j
然後遍歷殺怪的個數(正序遍歷)完全背包 k
得出dp[j][k] = max(dp[j][k],dp[j-cost[i]][k-1] + data[i]);
在這裏要記錄一下,要保留最大的耐久值,我們就要存儲,當dp[j][k]所產生的經驗值大於等於升級所需要的經驗值時小號的最小耐久值
最後一減就ok了
#include <iostream> #include <cstdio> #include <string.h> #include <cmath> #define inf 0xffffff using namespace std; const int maxn = 200; int dp[maxn][maxn];//dp[i][j]表示忍耐度為i的情況下殺j個怪獸所獲得的經驗 int data[maxn]; int cost[maxn]; int main() { int e,V,n,limit; while(~scanf("%d%d%d%d",&e,&V,&n,&limit)) { for(int i = 0;i < n;i++) scanf("%d %d",&data[i],&cost[i]); memset(dp,0,sizeof(dp)); int res = inf; for(int i = 0;i < n;i++)//遍歷物品 for(int j = cost[i];j <= V;j++)//完全背包層層遞推 for(int k = 1;k <= limit;k++)//不管當前這只,管當前這只 { dp[j][k] = max(dp[j][k],dp[j-cost[i]][k-1] + data[i]); if(dp[j][k] >= e)res = min(res,j); } if(res == inf)cout<<-1<<endl; else cout<<V - res<<endl; } return 0; }
HDU2159_二維完全背包問題