题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2159
解题思路: 这题很明显是完全背包,因为每种物品无限多。但一个小难点,就是还需要考虑最多杀怪数,也就是最多只能选K个物品。那么怎么办那? 其实并不难,那就多增加一层循环呗
多考虑一个杀怪数罢了 。F[U][V] 前 i 个物品个选V个物品装进容量为U的背包的最大价值。
所以转态转移方程: f [u][v] = max ( f [u][v] , f [u-b][v-1] + a ) 这里也就是多了个【v-1】,v-1是你将第 i 个装进包里,那么前面就只需再选 V-1 个物品。
这里的物品就是怪物,我只是把模型抽离出来便于理解。
代码:
#include <bits/stdc++.h> #define MAXS 106 #define INF 0x3f3f3f3f using namespace std; int f[MAXS][MAXS]; int n,m,k,s; int main(int argc, char const *argv[]) { int a,b; while(~scanf ("%d%d%d%d",&n,&m,&k,&s)) { memset(f,0,sizeof(f)); int ans = -1; for (int i = 0; i < k;++i) { scanf ("%d%d",&a,&b); for (int u = b; u <= m ; ++u) { for (int v = 1 ; v <= s ; ++v)//多增加了一层循环,处理怪的数量要求 { f[u][v] = max (f[u][v] , f[u-b][v-1] +a); if ( f[u][v] >= n) if ( (m - u) > ans ) //(m-n)表示剩余的疲劳值,如果更大就更新 ans = m - u ; } } } printf("%d ",ans); } return 0; }