勇士斗恶龙

版权声明:转载请附上地址 https://blog.csdn.net/weixin_44574520/article/details/88071859

勇士斗恶龙

题目描述

你的王国里有一条长着n个头的恶龙,你希望雇佣一些骑士把它杀死(即砍掉所有的头)。王国里有m个骑士可以雇佣,一个能力值为x(x <= 1000)的骑士可以砍掉恶龙一个直径不超过x的头,且需要支付x金币。如何雇佣骑士才能杀死恶龙,且需要支付最少的金币?注意:一个骑士只能砍掉一个龙头。

输入

输入文件:dragon.in

输入包含多组数据,每组数据第一行为正整数n和m(1 <= n,m <= 20000),第二行为n个整数,表示龙头的直径,第三行为m个整数,表示骑士的能力值,输入结束标志位n = m = 0。

输出

输出文件:dragon.out
对于每组数据,输出杀死恶龙的最少花费,若不能杀死,则输出“Loowater is doomed!”,各占一行。
样例输入
2 3
5 4
7 8 4
2 1
5 5
10
0 0

样例输出
11
Loowater is doomed!

题目分析:

很显然,一个具有x能力值的士兵能杀死一个半径不超过x的头,如果x能力值的士兵刚好去杀掉a==x的头,就不会造成浪费,如果让一个1000能力值的士兵去杀1半径的头,显然大材小用,费用也不会最少;
所以,我们重点解决不浪费问题,就能使费用最小;

给龙的头半径和士兵的能力值都从小到大排序;
枚举要砍的龙头的半径,每次选择一个能量值大于等于他的半径的最小的能量值的士兵;

Code:

#include <bits/stdc++.h>
using namespace std;
#define maxn 20010

int n,m,a[maxn],x[maxn],vis[maxn];

inline int read_() {
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9') {
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9') {
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}

inline void clean_() {
	memset(a,0,sizeof(a));
	memset(x,0,sizeof(x));
	memset(vis,0,sizeof(vis));
}

inline void work_() {
	int ans=0,last=1;
	for(int i=1;i<=n;i++) {
		int bj=0;
		for(int j=last;j<=m;j++) {
			if(vis[j]) continue;
			if(x[j]>=a[i]) {
				ans+=x[j];
				vis[j]=1;
				bj=1;
				last=j+1;
				break;
			}
	   }
	   if(!bj) {
	   	printf("Loowater is doomed!\n");
	   	return;
	   }
	}
	printf("%d\n",ans);
	return;
}

int main() {
	while(scanf("%d%d",&n,&m)==2&&n&&m) {
		clean_();
		for(int i=1;i<=n;i++) {
			a[i]=read_();
		}
		sort(a+1,a+n+1);
		for(int i=1;i<=m;i++) {
			x[i]=read_();
		}
		sort(x+1,x+m+1);
		work_();
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44574520/article/details/88071859
今日推荐