您的位置:首页 > 其它

ICPCCamp 2016 Day 6 - Spb SU and Spb AU Contest(Greedy Game-贪心)

2016-02-24 20:10 405 查看
有n≤105n \le 10^5 个物品,每个物品有价值ai,bia_i,b_i,现在2人轮流取值,先手的策略是从aia_i最大的物品中任取一个,问后手可能取得的最大bib_i和

把元素按aia_i为第一关键字,bib_i为第二关键字排序,现在每次先手都取最前的

我们考虑截至到前n-1个时的最优解已知,考虑第n个

显然如果n是第偶数个那么必取,

n是第奇数个时,考虑如果取这个数,只要拿之前取的任意一个换(显然仍合法)

可以用反证法证明贪心正确。

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <functional>
#include <cstdlib>
#include <queue>
#include <stack>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define Rep(i, n) for (int i = 1; i <= (n); ++i)
#define FOR(i, c) for(__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define clr(x, a) memset(x, (a), sizeof x)
#define RD(x) scanf("%d", &x)
#define PB push_back
#define MP make_pair
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
ll ans=0;
struct node{
int a,b,ranka,rankb;
}p[2000000];
int cmpa(node a,node b){
if (a.a==b.a) return a.b>b.b;
return a.a>b.a;
}
int cmpb(node a,node b){
if (a.b==b.b) return a.a>b.a;
return a.b>b.b;
}
int n;
priority_queue<int,vector<int>,greater<int> > q;
int main() {
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&p[i].a);
for (int i=1;i<=n;i++)
scanf("%d",&p[i].b);
sort(p+1,p+1+n,cmpa);
for (int i=1;i<=n;i++) p[i].ranka=i;

ans=0;
for(int i=2;i<=n;i+=2) ans+=p[i].b;
for(int i=2;i<=n;i+=2) {
q.push(p[i].b);
if (!q.empty()) {
int top=q.top();
if (i<n) if (top < p[i+1].b ) q.pop(),q.push(p[i+1].b),ans=ans+p[i+1].b-top;
}
}
cout<<ans<<endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: