/**//* 题意: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
搜索
最新评论
|
|