题目链接: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 }