https://www.cnblogs.com/violet-acmer/p/9852294.html
题解:
思路一:完全背包转“01”背包
考虑到第ki个怪最多杀min(m/b[ki],s)个,于是可以把第ki个怪转化为min(m/b[ki],s)个忍耐度及经验值均不变的怪,然后求解这个01背包问题。
(1):不用滚动数组优化
本题有三个限制条件①怪物种类②忍耐度③杀怪数。
如果不使用滚动数组优化空间,则需要开个三维数组dp[ maxMaster ][ max_m ][ max_s ]。
dp[ tot ][ i ][ j ]的含义是杀第tot个怪时,耗费 i 个忍耐度和 j 个杀怪数所获得的最大经验值。
1 void Solve() 2 { 3 int tot=0;//把所有的 ki 怪转化为min(s,m/b[ki])个忍耐度及经验值均不变的物品时的总个数 4 for(int kind=1;kind <= k;++kind) 5 { 6 int x=min(s,m/b[kind]);//第 ki 个怪最多可转化成 x 个 7 while(x--)//将这 x 依次加入到背包中 8 { 9 for(int i=1;i <= m;++i)//当前耗费的忍耐度 10 for(int j=1;j <= s;++j)//当前杀怪数 11 if(i >= b[kind]) 12 dp[tot][i][j]=max(dp[tot-1][i][j],dp[tot-1][i-b[kind]][j-1]+a[kind]); 13 else 14 dp[tot][i][j]=dp[tot-1][i][j]; 15 tot++; 16 } 17 } 18 }