51nod1475(贪心&枚举)

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1475

 

题意:中文题诶~

 

思路:看懂题意后,首先想到的是贪心:

按照人数非递增排序,对于当前城市尽量将其排在离首都远的地方,这样得到的人数显然是最大的;

对于最右边可以放两个城市,我一开始是将其余城市都安排好,再从剩下的城市中选择一个人数尽量多的。然而wa了;

举一个反例:

  5 5

  4 1

  3 2

  2 3

  1 4

  1 4

按照这个思路得到的答案是13,但显然正确答案是14;

显然右边多出的一个城市不能最后再选,因为本来多出的那个城市可能会在前面贪心时就被选走了;

解决的方法很简单,既然放后面不行,那先确定多出的那个城市就好了,所以可以先枚举多出那个城市,再按照前面的思路贪心剩下的城市就好了。。。

 

代码:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <map>
 4 #include <string.h>
 5 using namespace std;
 6 
 7 const int MAXN=1e5+10;
 8 map<int, bool> vis;
 9 struct node{
10     int hi, pi;
11 }gg[MAXN];
12 
13 bool cmp(node a, node b){
14     return a.pi==b.pi?a.hi<b.hi:a.pi>b.pi;
15 }
16 
17 int main(void){
18     int n, k, num=0;
19     cin >> n >> k;
20     for(int i=0; i<n; i++){
21         cin >> gg[i].hi >> gg[i].pi;
22     }
23     sort(gg, gg+n, cmp);
24     for(int j=0; j<n; j++){
25         if(gg[j].hi>=k) continue;
26         vis.clear();
27         int ans=gg[j].pi, cnt=0;
28         for(int i=0; i<n; i++){
29             if(i==j||gg[i].hi<gg[j].hi||cnt>=k-gg[j].hi) continue;
30             int x=k-gg[i].hi;
31             while(vis[x]&&x>=0){
32                 x--;
33             }
34             if(x>0){
35                 vis[x]=true;
36                 ans+=gg[i].pi;
37                 cnt++;
38             }
39         }
40         num=max(num, ans);
41     }
42     cout << num << endl;
43     return 0;
44 }
View Code

 

posted @ 2017-04-17 17:34  geloutingyu  阅读(128)  评论(0编辑  收藏  举报