题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2297
题意:游戏者必须打败给定数量的怪,才能获得胜利。而除了boss只能放在最后一个打之外,其余打怪的顺序随意,每打一个怪,需要一定的血量,打败后可以获得一定的血量,开始的血量为100,打怪过程中,血量如果少于0,则失败,游戏者血量最多为100。当打某一个怪物时,必须首先达到打败该怪物需要的血量,否则不能打该怪物。求是否能够把所有的怪物干掉。
类型:状态压缩+dp
思路:设置一个数组dp ,dp[1<<i]表示打完第i个怪物后,所剩余的血量,根据题目意思,那么就是求dp[1<<n]是否大于p(p代表打败boss所需要的血量)。二进制的0表示不打这个怪物,1表示打怪
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
using namespace std;
int dp[1<<21];
int c[22];
int r[22];
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=0; i<n-1; i++)
scanf("%d%d",&c[i],&r[i]);
int p;
scanf("%d",&p);
memset(dp,-1,sizeof(dp));
dp[0]=100;
int j;
for(j=0; j<(1<<(n-1)); j++)//状态压缩
for(int i=0; i<n-1; i++)
{
if((j&(1<<i))||dp[j]<c[i])//这个怪物已经打过了,或者上次剩余的血量不够打下这个怪物
continue;
int hp=dp[j]-c[i]+r[i];//打下该怪物后,最终的血量
if(hp>100)//维护血量不超过100
hp=100;
if(dp[j|(1<<i)]<hp)//如果存在与现有状态相同的状态,但是血量少于现有状态,则更新该状态的血量
dp[j|(1<<i)]=hp;
}
if(dp[j-1]>=p)//注意此处的j-1,而不是j
cout<<"clear!!!"<<endl;
else cout<<"try again"<<endl;
}
return 0;
}