你的王国里有一条n个头的恶龙,你希望雇佣一些骑士把它杀死(也就是砍掉所有的头)。村里有m个骑士可以雇佣,一个能力值为 x 的骑士可以砍掉恶龙一个直径不超过 x 的头,且需要支付 x 个金币。如何雇佣骑士才能砍掉恶龙所有的头,并且支付最小的金币?注意,一个骑士只能砍一个头并且仅能被雇佣1次

  因为要保证用的钱最少,所以先把骑士按照能力值从小到大进行排序。然后从最小的开始一个一个进行匹配。在进行匹配的时候又出现一个问题,那就是每个骑士只能雇佣一次。这里有2个处理方法,第一个是开一个数组用来标记该骑士是否被雇佣。另外一个就是,将龙头也按照从小到大进行排序,从小龙头和能力值低的其实开始匹配,并保留匹配到的位置。


拿下面这组数据进行模拟:

2 3
8
5
7
8
4
将数据排序之后如下:
龙头:5 8
骑士:4 7 8
 
第一轮匹配,从第一个头和第一个骑士开始。发现第一个骑士不能够砍掉第一个头。再匹配第一个头和第二个骑士,发现可以砍掉第一个头,所以雇佣这个骑士。
 
第二轮匹配,将第二个头和第三个骑士开始匹配(因为,第一个骑士连 <= 当前龙头的龙头都不能砍掉,就更不能砍掉后面的龙头),发现可以砍掉第二个头,所以雇佣这个骑士。
 
最后输出的结果为:
15
 

这道题目是一个非常简单的 排序 + 贪心。

附AC代码:

#include <stdio.h>
#include <math.h>
#include <iostream>
#include <cstdarg>
#include <algorithm>
#include <string.h>
#include <stdlib.h>
#include <string>
#include <list>
#include <vector>
#include <map>
long
sizeof(a))
namespace std;
  15:  
int count, ...)
  17: {
  18:     va_list arg_ptr;
  19:     va_start (arg_ptr, count);
int i = 0; i < count; i++)
int*));
  22:     va_end(arg_ptr);
  23: }
  24:  
int d[20009], p[20009];
  26:  
int main()
  28: {
int n, m, kill, pay;
, &n, &m) && (n || m))
  31:     {
  32:         Clean(2, d, p);
int i = 1; i <= n; i++)
, &d[i]);
int i = 1; i <= m; i++)
, &p[i]);
  37:         sort(d + 1, d + n + 1);
  38:         sort(p + 1, p + m + 1);
  39:         kill = pay = 0;
int i = 1, j = 1; i <= n && j <= m; i++)
  41:         {
while (d[i] > p[j]) j++;
if (p[j] >= d[i]) kill += 1, pay += p[j++];
  44:         }
, pay);
);
  47:     }
return 0;
  49: }

相关文章: