P1650 赛马

题目描述

我国历史上有个著名的故事: 那是在2300年以前。齐国的大将军田忌喜欢赛马。他经常和齐王赛马。他和齐王都有三匹马:常规马,上级马,超级马。一共赛三局,每局的胜者可以从负者这 里取得200银币。每匹马只能用一次。齐王的马好,同等级的马,齐王的总是比田忌的要好一点。于是每次和齐王赛马,田忌总会输600银币。

田忌很沮丧,直到他遇到了著名的军师――孙膑。田忌采用了孙膑的计策之后,三场比赛下来,轻松而优雅地赢了齐王200银币。这实在是个很简单的计 策。由于齐王总是先出最好的马,再出次好的,所以田忌用常规马对齐王的超级马,用自己的超级马对齐王的上级马,用自己的上级马对齐王的常规马,以两胜一负 的战绩赢得200银币。实在很简单。

如果不止三匹马怎么办?这个问题很显然可以转化成一个二分图最佳匹配的问题。把田忌的马放左边,把齐王的马放右边。田忌的马A和齐王的B之间,如果 田忌的马胜,则连一条权为200的边;如果平局,则连一条权为0的边;如果输,则连一条权为-200的边……如果你不会求最佳匹配,用最小费用最大流也可 以啊。 然而,赛马问题是一种特殊的二分图最佳匹配的问题,上面的算法过于先进了,简直是杀鸡用牛刀。现在,就请你设计一个简单的算法解决这个问题。

输入输出格式

输入格式:

第一行一个整数n,表示他们各有几匹马(两人拥有的马的数目相同)。第二行n个整数,每个整数都代
表田忌的某匹马的速度值(0 <= 速度值<=
100)。第三行n个整数,描述齐王的马的速度值。两马相遇,根据速度值的大小就可以知道哪匹马会胜出。如果速度值相同,则和局,谁也不拿钱。

【数据规模】

对于20%的数据,1<=N<=65;

对于40%的数据,1<=N<=250;

对于100%的数据,1<=N<=2000。

输出格式:

仅一行,一个整数,表示田忌最大能得到多少银币。

输入输出样例

输入样例#1:

3
92 83 71
95 87 74
输出样例#1:

200

这是一道让人吐血的好题。。

先来想想贪心策略(这里一定要理清思路,慢慢来,别急):
如果总是用最弱的马 去打对面最强的马,可能不是最优,因为这里有平局的情况存在,选择平局可能比赢给最强的马更合算
(譬如:田忌 2 3 10 齐威王:2 8 9)
因此,我们要这样去分析:
先看最弱的马之间的实力,如果我方最弱的马比对方最弱的马强,就直接怼掉。这个比较显然,既然我方最弱的马更强,那么我方其它马一定可以怼掉对方最弱的马,但杀鸡焉用牛刀?
如果我方的马比对方的马弱或者相等:
有一种策略是用最弱的马去怼最强的马,让“炮灰”的作用发挥到极值,
另一种策略是先看最强的马之间的关系。 我们来分别讨论这两种策略,并证明两种策略都是正确的:
1、用最弱的马去怼最强的马,这样输了一盘,但这一盘是早晚要输的。如果最弱的马等于对方最弱的马,那么怼掉对方最强马,一定有其它马可以赢回来;如果最弱的马小于对方最弱的马,那么必然小于对方所有马,这是必然的。因此应让它去怼掉对方最强的,让我放最强的能够成功得分道路进一步开阔。
2、先看最强的马之间的关系。如果我方最强马比对方更强,就怼掉,否则就应该让最弱的马去怼对方最强的马。因为我方最强的马虽然打不过敌方最强马,但说不定可以打过第二强、第三强……但是最弱的马却一定赢不了所有的马。
两条结合着来,差不多了就。。。
但是还有一种特殊情况:最弱的马平局,最强的马平局,且最弱的马等于最强的马
这时所有对决均为平局,直接输出答案即可。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define max(a,b) ((a) > (b) ? (a) : (b))
#define min(a,b) ((a) > (b) ? (b) : (a))
#define lowbit(a) ((a) & (-(a))) int read()
{
int x = 0;char ch = getchar();char c = ch;
while(ch > '9' || ch < '0')c = ch, ch = getchar();
while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
if(c == '-')return -x;
return x;
}
const int INF = 0x3f3f3f3f;
const int MAXN = 2000 + 10; int n,tian[MAXN],qi[MAXN];
int ans; inline void init()
{
n = read();
for(int i = 1;i <= n;i ++)
{
tian[i] = read();
}
std::sort(tian + 1, tian + 1 + n);
for(int j = 1;j <= n;j ++)
{
qi[j] = read();
}
std::sort(qi + 1, qi + 1 + n);
}
inline void put()
{
printf("%d", ans * 200);
}
inline void tan()
{
int head1 = 1,tail1 = n,head2 = 1,tail2 = n;
while(head1 <= tail1)
{
if(tian[head1] > qi[head2]) head1 ++,head2 ++,ans ++;
else if(tian[head1] < qi[head2]) head1 ++,tail2 --,ans --;
else//平局
{
if(tian[tail1] > qi[tail2])tail1 --, tail2 --, ans ++;
else if(tian[head1] < qi[tail2])head1 ++, tail2 --, ans--;//注意!!
else break;
}
}
} int main()
{
init();
tan();
put();
return 0;
}

洛谷P1650 赛马[2017年5月计划 清北学堂51精英班Day1]的更多相关文章

  1. 洛谷P2258 子矩阵[2017年5月计划 清北学堂51精英班Day1]

    题目描述 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取第2.4行和第2.4.5列交叉位置的元素 ...

  2. 洛谷P1080 [NOIP2012提高组D1T2]国王游戏 [2017年5月计划 清北学堂51精英班Day1]

    P1080 国王游戏 题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右 手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排 ...

  3. 洛谷P2327 [SCOI2005]扫雷 [2017年5月计划 清北学堂51精英班Day1]

    P2327 [SCOI2005]扫雷 题目描述 输入输出格式 输入格式: 第一行为N,第二行有N个数,依次为第二列的格子中的数.(1<= N <= 10000) 输出格式: 一个数,即第一 ...

  4. 【模板】KMP [2017年5月计划 清北学堂51精英班Day2]

    Day2就搞一个KMP把  马拉车.AC自动机等准备省选的时候再说.. 模板题: 1204 寻找子串位置 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 青铜 Bronze     ...

  5. 洛谷P1352 没有上司的舞会 [2017年5月计划 清北学堂51精英班Day3]

    P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子 结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职 ...

  6. 【模板】倍增LCA [2017年5月计划 清北学堂51精英班 Day3]

    P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...

  7. 【模板】tyvjP1520 树的直径 [2017年5月计划 清北学堂51精英班Day3]

    P1520 树的直径 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 树的直径,即这棵树中距离最远的两个结点的距离.每两个相邻的结点的距离为1,即父亲结点与儿 ...

  8. 【模板】 递归线段树 [2017年五月计划 清北学堂51精英班Day4]

    P3372 [模板]线段树 1 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别 ...

  9. 洛谷P2835 刻录光盘 [2017年6月计划 强连通分量02]

    P2835 刻录光盘 题目描述 在JSOI2005夏令营快要结束的时候,很多营员提出来要把整个夏令营期间的资料刻录成一张光盘给大家,以便大家回去后继续学习.组委会觉得这个主意不错!可是组委会一时没有足 ...

随机推荐

  1. webpack新手名词解释……妈妈再也不担心我看不懂webpack官方文档了

    __dirname : 在任何模块文件内部,可以使用__dirname变量获取当前模块文件所在目录的完整绝对路径. path.resolve(): 方法将一系列路径或路径段解析为绝对路径. 语法: p ...

  2. svn使用方法以及使用教程

    一.什么是svnSVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS. 二.svn的下载安装下载地址:https: ...

  3. 深入浅出 Java Concurrency (34): 线程池 part 7 线程池的实现及原理 (2)[转]

    线程池任务执行流程 我们从一个API开始接触Executor是如何处理任务队列的. java.util.concurrent.Executor.execute(Runnable) Executes t ...

  4. java分析工具arthas

    wget https://alibaba.github.io/arthas/arthas-boot.jar java -jar arthas-boot.jar --target-ip 0.0.0.0

  5. Android数据适配器Adapter简介

    1.简介 Adapter是用来帮助填充数据的中间桥梁,简单点说就是:将各种数据以合适的形式显示到view上,在常见的View(List View,Grid View)等地方都需要用到Adapter! ...

  6. privoxy 安装

    https://www.privoxy.org/sf-download-mirror/Sources/ 1.挑选源码版本,下载,解压 2.增加用户 useradd privoxy 3.make &am ...

  7. Struts2中param的作用

    1.页面传参与配置传参的区别:如果页面Form表单的参数在Action类中有相应的setter方法,则会优先取页面Form表单传过来的值,如果页面没有该属性同名的参数,则会从配置文件中取同名的参数值作 ...

  8. Flask ——路由系统

    Flask中的路由系统其实我们并不陌生了,从一开始到现在都一直在应用 @app.route("/",methods=["GET","POST" ...

  9. python学习笔记4.2_正则表达式

    常用正则表达式:http://tool.chinaz.com/regex/ 1.正则表达式:提供了一种在文本中灵活查找或匹配字符串模式的方法.单个表达式通常被称为regex. 2.python的re模 ...

  10. 2019-8-31-dotnet-启动-JIT-多核心编译提升启动性能

    title author date CreateTime categories dotnet 启动 JIT 多核心编译提升启动性能 lindexi 2019-08-31 16:55:58 +0800 ...