版权声明:转载请附上地址 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;
}