SPOJ:One piece(不错的带权括号最大匹配问题)
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.
Input
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.
Output
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.
Constraints
2 ≤ n ≤ 500 000
1 ≤ ai ≤ 109
1 ≤ bi ≤ 109
Note that a1, a2, …, an are n distinct integers.
Example
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=;
struct in{
int a,b,id;
in(){ a=b=id=;}
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=;
scanf("%d",&N);
for(i=;i<=N;i++) scanf("%d",&s[i].a);
for(i=;i<=N;i++) scanf("%d",&s[i].b);
for(i=;i<=N;i++) s[i].id=i;
sort(s+,s+N+,cmp);
for(i=N;i>=;i--){
if(i%==){
if(Set.empty()) ans+=s[i].b,vis[s[i].id]=;
else {
set<in>::iterator it=Set.begin();
if((*it).b>s[i].b){
ans+=(*it).b; vis[(*it).id]=;
Set.insert(in(s[i].b,s[i].id));
Set.erase(it);
}
else {
vis[s[i].id]=; ans+=s[i].b;
}
}
}
else Set.insert(in(s[i].b,s[i].id));
}
int sum1=,sum2=;
for(i=N;i>=;i--){
if(vis[s[i].id]) L[++sum1]=s[i].id;
else R[++sum2]=s[i].id;
}
printf("%lld\n",ans);
for(i=;i<=N/;i++) printf("%d %d\n",L[i],R[i]);
return ;
}
SPOJ:One piece(不错的带权括号最大匹配问题)的更多相关文章
- HDU 2255 奔小康赚大钱(带权二分图最大匹配)
HDU 2255 奔小康赚大钱(带权二分图最大匹配) Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊 ...
- Luogu 1559 运动员最佳匹配问题(带权二分图最大匹配)
Luogu 1559 运动员最佳匹配问题(带权二分图最大匹配) Description 羽毛球队有男女运动员各n人.给定2 个n×n矩阵P和Q.P[i][j]是男运动员i和女运动员j配对组成混合双打的 ...
- UVA1349(带权二分图最大匹配 --> KM算法模板)
UVA1349 题意:给定一些有向带权边,求出把这些边构造成一个个环,总权值最小 解法: 对于带权的二分图的匹配问题可以用通过KM算法求解. 要求最大权匹配就是初始化g[i][j]为0,直接跑就可以: ...
- 带权二分图最大匹配KM算法
二分图的判定 如果一个图是连通的,可以用如下的染色法判定是否二分图: 我们把X部的结点颜色设为0,Y部的颜色设为1. 从某个未染色的结点u开始,做BFS或者DFS .把u染为0,枚举u的儿子v.如果v ...
- "《算法导论》之‘图’":不带权二分图最大匹配(匈牙利算法)
博文“二分图的最大匹配.完美匹配和匈牙利算法”对二分图相关的几个概念讲的特别形象,特别容易理解.本文介绍部分主要摘自此博文. 还有其他可参考博文: 趣写算法系列之--匈牙利算法 用于二分图匹配的匈牙利 ...
- POJ 2195 Going Home | 带权二分图匹配
给个地图有人和房子 保证人==房子,每个人移动到房子处需要花费曼哈顿距离的代价 问让人都住在房子里最小代价 显然是个带权二分图最大匹配 转化成以一个网络,规定w是容量,c是代价 1.S向人连边,w=1 ...
- hdu4829 带权并查集(题目不错)
题意: Information Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...
- poj1417 带权并查集 + 背包 + 记录路径
True Liars Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2713 Accepted: 868 Descrip ...
- POJ1417:True Liars(DP+带权并查集)
True Liars Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
随机推荐
- hdu4862 2014多校B题/ 费用流(最优情况下用不大于K条路径覆盖)(不同的解法)
题意: 一个数字矩阵,可以出发K次,每次可以从右边或者下面走,要求(在收益最大情况下)覆盖全图,不能则输出-1.(规则:每次跳一步的时候若格子数字相等则获得该数字的能量,每跳一步消耗距离的能量).每个 ...
- 微软CIO如何与业务部门打交道?
微软公司副总裁兼CIO Tony Scott是一个非常智慧的人,他拒绝和CEO讨论IT成本的问题,认为IT不应该谈论成本,而是应该谈论IT提供服务的价值.在满足业务部门需求.为业务部门提供适当的IT支 ...
- 【Todo】git的fast forward & git命令学习 & no-ff
git的fast-forward在之前的文章有介绍过,但是介绍的不细: http://www.cnblogs.com/charlesblc/p/5953066.html fast-forward方式就 ...
- SolidEdge 如何绘制断裂剖视图 局部剖视图
1 点击局部放大图,然后点击绘制按钮,然后点击选择要绘制的视图 2 绘制封闭的局部剖视图的剖面线(必须封闭,点击最后一个点封闭之后会变成蓝色虚线) 3 修改深度(不一定要在下图的右下角修改深度 ...
- 实现多线程的方式Runnable
package com.thread.runnable; /** * 实现多线程的方式有继承Thread类和实现Runnable接口两种方式 * 哪种方式更好呢?实现的方式由于继承的方式. * 原因: ...
- ubuntu搭建samba服务器
一.为什么要用Samba? Samba的主要任务就是实现Linux系统和Windows系统之间的资源共享. 二.需要的软件? 我是在ubuntu上实现的,所以我只需在配置好ubuntu的更 ...
- 【C语言】统计数字在排序数组中出现的次数
//数字在排序数组中出现的次数. //统计一个数字在排序数组中出现的次数.比如:排序数组{1,2,3,3,3,3,4,5}和数字3,因为3出现了4次,因此输出4. #include <stdio ...
- 文件宝局域网传输/播放功能Windows10系统经验贴(感谢文件宝用户@卡卡罗特 和@24K 純情)
本文由文件宝用户@卡卡罗特 和@24K 純情 两位用户提供,感谢二位. 先分享一个软件开发者的博客,http://www.cnblogs.com/flychen/也许里面的说明就能解决你的问题. 以下 ...
- poj3349(hash or violence)
Snowflake Snow Snowflakes Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 38600 Accep ...
- yum 安装 mysql
安装 yum -y install mysql-server 开机自启动 chkconfig mysqld on 设置账户密码 启动 service mysqld start -- 进入mysql库 ...