 /**//*
题意:N只鸟要攻击K个怪物,每只鸟有相应的power值n,每个怪物也有相应的生命值m
一只鸟刚放出时为young(n可以为0),攻击了怪物后变为old 当它的power变为0时就死掉了
规则为:
1) n>m 怪物死掉,下一个怪物出现
2) n=m 鸟,怪物同时死掉
3) n<m 鸟为young时,能让怪物损失n old时,不会损失
同时,可以使用M个魔法,每个魔法只能对一只鸟使用,可以使得它的power加倍
dp[i][j]表示前j只鸟使用了i个魔法最大杀死的怪物
这里用个pair来存
<first,second> 表示第first怪物还剩second的血,取-1表示已经死掉了(也即等价于first+1,saber[first+1])
由于power,生命值可以为0,比较繁琐,大致算法为:
对于新放出来的鸟j 设其power为 now
if(now <= blood )
blood -= now
blood 为0时标记-1死掉
else
杀死当前怪物,num++
while(now >0 && 能继续杀 ) //这里now不能为0,因为已经是old的了
now -= saber[num++]

*/
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;


pair<int,int> dp[105][10005];
int bird[10005],saber[100005];
int N,M,K;


inline pair<int,int> pmax( pair<int,int> &A , pair<int,int> &B)
  {
if(A.first > B.first )return A;
if(A.first == B.first && A.second < B.second)return A;
return B;
}

int DP()
  {
//-1 died
dp[0][0] = make_pair(0,-1);
for(int i=0;i<=M;i++)
for(int j=i?i:1;j<=N;j++)
 {
dp[i][j] = make_pair(0,-1);
//[i-1,j-1]
if(i)
 {
int now = bird[j]*2;
int num = dp[i-1][j-1].first;
int blood = dp[i-1][j-1].second;
//change
if(blood == -1)blood = saber[++num];
if(num>K)return K;
if(now <= blood)
 {
blood -= now;
if(blood == 0) blood = -1;
dp[i][j] = pmax(dp[i][j],make_pair(num,blood));
}
else
 {
now -= blood;
num++;
while(now && num<=K && now >= saber[num] )//now can't be 0 it's old
now -= saber[num++];
if(num>K)return K;
blood = saber[num];
dp[i][j] = pmax(dp[i][j],make_pair(num,blood));
}
}
//[i,j-1]
 {
int now = bird[j];
int num = dp[i][j-1].first;
int blood = dp[i][j-1].second;
//change
if(blood == -1)blood = saber[++num];
if(num>K)return K;
if(now <= blood)
 {
blood -= now;
if(blood == 0) blood = -1;
dp[i][j] = pmax(dp[i][j],make_pair(num,blood));
}
else
 {
now -= blood;
num++;
while(now && num<=K && now >= saber[num] )//now can't be 0 it's old
now -= saber[num++];
if(num>K)return K;
blood = saber[num];
dp[i][j] = pmax(dp[i][j],make_pair(num,blood));
}
}
}
if(dp[M][N].second!=-1)dp[M][N].first--;
return dp[M][N].first;
}

int main()
  {
//freopen("in","r",stdin);
while(scanf("%d%d%d",&N,&M,&K),N||M||K)
 {
M = min(N,M);//一定要加 上面的判断条件 j=i?i:1
for(int i=1;i<=N;i++)
scanf("%d",&bird[i]);
for(int i=1;i<=K;i++)
scanf("%d",&saber[i]);
printf("%d\n",DP());
}
return 0;
}
|
|
常用链接
随笔分类
Links
搜索
最新评论

|
|