标签:pos lin cer 思路 set number through second friend
One of DB and TN common interests is traveling. One day, they went to Grand Line and found One Piece !
The One Piece treasure has n gold coins (n is even). Both them like gold coins, but they evaluate them as different values. So they decided to divide those coins by following method :
DB and TN do n / 2 steps, at each step, DB choose 2 coins, TN takes the coin that she evaluates it greater, and DB take the rest coin.
Let’s help DB find how to take the maximum value at possible.
First line : a single integer n (n is even) – the number of coins
Second line : n integers a1, a2, …, an. ai is the value of ith coin that TN evaluates.
Third line : n integers b1, b2, …, bn. bi is the value of ith coin that DB evaluates.
First line : an integer S – the maximum value DB can take.
Last n / 2 lines : ith line contains two number x and y (1 ≤ x, y ≤ n), are the indexes of two
coins that DB choose on ith step. Each coin must be chose exact one time.
If there are multiple ways, just print any of them.
2 ≤ n ≤ 500 000
1 ≤ ai ≤ 109
1 ≤ bi ≤ 109
Note that a1, a2, …, an are n distinct integers.
Input: 6 6 10 11 18 5 14 1 7 6 12 15 1 Output: 28 5 1 2 6 3 4
Warning: large Input/Output data, be careful with certain languages
题意:有N个物品(N是偶数),对于每个物体,A同学和B同学都有自己的估值。每次A同学取出两个物体,B取走自己认为价值高的一个,然后A拿走剩下的一个,问A应该如果选择。使得A最后获得的价值最高。
思路:我们按B认为的价值排序,假设排成一排,左边大于右边,那么问题就成了:
错误思路:用优先队列,一开始把除了最右边的那个都放进队列里,从最右边开始匹配,找他左边的还没有被匹配的最小值匹配; 比如12 1 6 7 2 15。得到错误答案24。
正确打开方式:我们先假设把偶数的取走,然后如果右边的未取走的比它大,则可以替换。那么可以用单调队列搞。
#include<bits/stdc++.h> using namespace std; const int maxn=1000010; struct in{ int a,b,id; in(){ a=b=id=0;} in(int bb,int ii):b(bb),id(ii){} bool friend operator <(in x,in y){ return x.b>y.b; } }s[maxn]; bool cmp(in w,in v){ return w.a>v.a; } int vis[maxn]; set<in>Set; int L[maxn],R[maxn]; int main() { int N,i,j; long long ans=0; scanf("%d",&N); for(i=1;i<=N;i++) scanf("%d",&s[i].a); for(i=1;i<=N;i++) scanf("%d",&s[i].b); for(i=1;i<=N;i++) s[i].id=i; sort(s+1,s+N+1,cmp); for(i=N;i>=1;i--){ if(i%2==0){ if(Set.empty()) ans+=s[i].b,vis[s[i].id]=1; else { set<in>::iterator it=Set.begin(); if((*it).b>s[i].b){ ans+=(*it).b; vis[(*it).id]=1; Set.insert(in(s[i].b,s[i].id)); Set.erase(it); } else { vis[s[i].id]=1; ans+=s[i].b; } } } else Set.insert(in(s[i].b,s[i].id)); } int sum1=0,sum2=0; for(i=N;i>=1;i--){ if(vis[s[i].id]) L[++sum1]=s[i].id; else R[++sum2]=s[i].id; } printf("%lld\n",ans); for(i=1;i<=N/2;i++) printf("%d %d\n",L[i],R[i]); return 0; }
SPOJ:One piece(最大匹配问题)(Gut Problem!)
标签:pos lin cer 思路 set number through second friend
原文地址:https://www.cnblogs.com/hua-dong/p/9058008.html