题目
题解思路
花费1 精灵球
花费2 体力值
状态表示
f[i , j , k ] 只从前i个商品中选 花费1不超过j 花费2 不超过 k-1 的所有抓捕方法的抓捕个数 最大值
状态计算
不选
f[ i , j , k ] = f[ i-1 , j , k ] ;
选
f[ i , j , k ] = max(f[ i-1 , j , k ] , f[ i -1 , j - h[i] , k - w[i] ) ;
最小体力值就直接往后搜出最佳答案即可
因为体力值不能低于1 ,所以每次我们必须预留1 的体力值 ,即 k从 0 到 k-1的情况中检索
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
using namespace std;
const int INF = 0x3f3f3f3f;
int dp[1510][1010];
int w[110] , h[110] ;
int main ()
{
ios::sync_with_stdio(false);
int n,m,k , ans = 0 ;
cin>>n>>m>>k;
for ( int i = 1 ; i <= k ; i++ )
{
cin>>w[i]>>h[i];
}
for (int i = 1 ; i <= k ; i++ )
{
for ( int j = n ; j >= w[i] ; j-- )
{
for (int p = m -1 ; p >= h[i] ; p-- )
{
dp[j][p] = max( dp[j][p] , dp[j-w[i]][p-h[i]] + 1 );
}
}
}
for (int i = 0 ; i < m ; i++ )
if ( dp[n][i] == dp[n][m-1] )
{
ans = i ;
break;
}
cout<<dp[n][m-1]<<" "<<m-ans<<"\n";
return 0 ;
}