上海五校赛 战斗
战斗
发布时间: 2017年7月9日 18:17 最后更新: 2017年7月9日 21:05 时间限制: 2000ms 内存限制: 128M
最近,盛大计划开发一款手游,以下是简化版。系统和我方各有n 头怪兽,每一头怪兽都有生命值和攻击力,并且当怪兽A攻击怪兽B,如果怪兽B的生命值高于怪兽A的攻击力,则怪兽B的生命力减少A的攻击力的数值,否则怪兽B将死亡。我方已经通过一些手段得知了系统怪兽的出战序列,我方想要知道,我方是否可以合理安排怪兽的出战序列,保证当系统的n 头怪兽全部死亡时,而我方至少还存在一头怪兽。
所有怪兽是每秒攻击一次,即如果A和B战斗,A受到B的伤害的同时,B也受到A的伤害,直到一方死亡,换序列中的下一个怪兽,继续战斗。
第一行一个整数T ,表示测试组数。
对于每组数据,第一行输入一个整数n
,1<=n<=10
, 表示怪兽的数目。
接下来n
行,表示系统n
头怪兽的出战序列,每一行两个整数v
,a
, 1<=v<=1000
, 1<=a<=100
. 其中v
表示生命值,a
表示攻击力。
接下来n
行,表示我方n
头怪兽,但是出战序列可以由我方自己安排。每行两个整数,含义类似。
每组数据输出一行。如果我方可以通过合理安排怪兽的出战序列,保证当系统的n 头怪兽全部死亡,而我方至少还存在一头怪兽,那么输出YES;否则输出NO
复制
2 2 5 4 4 3 3 2 5 4 2 5 4 4 3 3 2 5 5
NO YES
分析:状压dp,如果选择当前集合使得干掉的怪兽更多且需要干掉的下一个怪兽血更少,则转移;
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <bitset> #include <map> #include <queue> #include <stack> #include <vector> #include <cassert> #include <ctime> #define rep(i,m,n) for(i=m;i<=(int)n;i++) #define mod 1000000007 #define inf 0x3f3f3f3f #define vi vector<int> #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) #define pii pair<int,int> #define sys system("pause") #define ls rt<<1 #define rs rt<<1|1 const int maxn=1e5+10; const int N=5e2+10; using namespace std; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p%mod;p=p*p%mod;q>>=1;}return f;} int n,m,k,t,v[2][11],a[2][11],dp[2][1<<11]; int main() { int i,j; scanf("%d",&t); while(t--) { memset(v,0,sizeof(v)); scanf("%d",&n); rep(i,0,n-1)scanf("%d%d",&v[0][i],&a[0][i]); rep(i,0,n-1)scanf("%d%d",&v[1][i],&a[1][i]); memset(dp[0],0,sizeof(dp[0])); memset(dp[1],inf,sizeof(dp[1])); dp[0][0]=0; dp[1][0]=v[0][0]; bool flag=false; rep(i,0,(1<<n)-1) { rep(j,0,n-1) { if(i>>j&1)continue; int tx=dp[1][i],ty=v[1][j]; rep(k,dp[0][i],n-1) { while(tx>0&&ty>0)tx-=a[1][j],ty-=a[0][k]; if(ty<=0)break; else tx=v[0][k+1]; } if(i==((1<<n)-1)&&ty>0&&k==n)flag=true; if(i!=((1<<n)-1)&&k==n)flag=true; if(dp[0][i|(1<<j)]<k||(dp[0][i|(1<<j)]==k&&dp[1][i|(1<<j)]>tx)) { dp[0][i|(1<<j)]=k; dp[1][i|(1<<j)]=tx; } } } puts(flag?"YES":"NO"); } return 0; }