传送门

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 }
View Code

相关文章: