輸入有:經驗,忍耐度,怪物種數,限制殺怪數 每一種怪物對應得到的經驗值和消耗的耐久值ios
輸出:剩下的最大忍耐度spa
限制:忍耐度,殺怪個數code
在這裏把忍耐度當作揹包的容量,殺怪個數限制做爲第二維blog
dp[i][j]表示在揹包容量爲i的時候,放了j件物品所產生的價值get
接下來就是循環問題string
先遍歷每個物品(怪物) iit
而後遍歷體積(耐久值)正序遍歷——徹底揹包 jio
而後遍歷殺怪的個數(正序遍歷)徹底揹包 kclass
得出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; }