题意:给出忍耐度和杀怪数量和升级所需经验,并且已知每只怪的经验和所需的忍耐值,求出是否能升级
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2159
思路:有忍耐度和杀怪数量两个限制条件,二维背包,并且每种怪物没有数量限制,完全背包,综合就是二维完全背包。状态转移方程为dp[j][l] = max ( dp[j][l], dp[j-num[i].b][l-1] + num[i].a )
注意点:没说怪物的数量,不能当做01背包
以下为AC代码:
Run ID | Submit Time | Judge Status | Pro.ID | Exe.Time | Exe.Memory | Code Len. | Language | Author |
12317017 | 2014-11-27 00:03:40 | Accepted | 2159 | 46MS | 440K | 1394 B | G++ | luminous11 |
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <deque>
#include <list>
#include <cctype>
#include <algorithm>
#include <climits>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;
struct node{
int a;
int b;
}num[105];
int dp[105][105];
int main()
{
int m, n, s, k;
while ( cin >> n >> m >> k >> s )
{
for ( int i = 0; i < k; i ++ )
{
cin >> num[i].a >> num[i].b;
}
memset ( dp, 0, sizeof ( dp ) );
for ( int i = 0; i < k; i ++ )
{
for ( int j = num[i].b; j <= m; j ++ )
{
for ( int l = 1; l <= s; l ++ )
{
dp[j][l] = max ( dp[j][l], dp[j-num[i].b][l-1] + num[i].a );
}
}
}
bool flag = 0;
for ( int i = 0; i <= m && ! flag; i ++ )
{
for ( int j = 0; j <= s && ! flag; j ++ )
{
if ( dp[i][j] >= n )
{
flag = 1;
cout << m - i << endl;
}
}
}
if ( ! flag )
{
cout << "-1" << endl;
}
}
return 0;
}