题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2297
题目大意:你初始血量为100,现在有一个打怪游戏,有N-1个小怪,每个小怪有一个防御值down,如果你的初始血量大于等于防御值时,你可以杀死该小怪,并恢复up的血量,当然,你的血量上限为100,这些小怪的击杀顺序你来选择,但是最后要杀死 Boss才算获胜,boss也有一个防御值,问你能否清除所有怪物。
解题思路:定义dp[i][j]为在状态i 击杀小怪j能得到的最大血量,dp[i]=max(dp[i],dp[i|(1<<j)]-down[j]+up[j]);
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
int n,all;
int dp[1<<22],down[22],up[22];
void solve()
{
memset(dp,0,sizeof(dp));
int num=(1<<n);
dp[num-1]=100;
for(int i=num-2; i>=0; i--)
{
dp[i]=-inf;
for(int j=0; j<n; j++)
{
if(!(i&(1<<j)))
{
if(dp[i|(1<<j)]>=down[j])
dp[i]=max(dp[i],dp[i|(1<<j)]-down[j]+up[j]);
}
if(dp[i]>100) dp[i]=100;
}
}
if(dp[0]>=all) printf("clear!!!\n");
else printf("try again\n");
}
int main()
{
while(~scanf("%d",&n))
{
n--;
memset(down,0,sizeof(down));
memset(up,0,sizeof(up));
for(int i=0;i<n;i++)
scanf("%d%d",&down[i],&up[i]);
scanf("%d",&all);
solve();
}
return 0;
}