输入有:经验,忍耐度,怪物种数,限制杀怪数 每一种怪物对应得到的经验值和消耗的耐久值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; }