tyvj1048 田忌赛马
描述
输入格式
第二行有N个整数表示田忌的马的速度。
第三行的N个整数为齐王的马的速度。
输出格式
测试样例1
输入
3
92 83 71
95 87 74
输出
200
这个问题很显然可以转化成一个二分图最佳匹配的问题。把田忌的马放左边,把齐王的马放右边。田忌的马A和齐王的B之间,如果田忌的马胜,则连一条权为200的边;如果平局,则连一条权为0的边;如果输,则连一条权为-200的边。
然而我们知道,二分图的最佳匹配算法的复杂度很高,无法满足N=2000的要求。
我们不妨用贪心思想来分析一下问题。因为田忌掌握有比赛的“主动权”,他总是根据齐王所出的马来分配自己的马,所以这里不妨认为齐王的出马顺序是按马的速度从高到低出的。由这样的假设,我们归纳出如下贪心策略:
1、如果田忌剩下的马中最强的马都赢不了齐王剩下的最强的马,那么应该用最差的一匹马去输给齐王最强的马。
2、如果田忌剩下的马中最强的马可以赢齐王剩下的最强的马,那就用这匹马去赢齐王剩下的最强的马。
3、如果田忌剩下的马中最强的马和齐王剩下的最强的马打平的话,可以选择打平或者用最差的马输掉比赛。
第一个贪心策略的证明:
此时田忌的所有马都赢不了齐王的马,所以无论用最慢马去输还是用最快的马去输都同样是输,而处于贪心的思想,我们应该保留相比之下更强的马,因此用最慢的马去输一定不会比用别的马去输来得劣,所以这是最优策略。
证毕。
第二个贪心策略的证明:
假设现在齐王剩下的最强的马是A,田忌剩下的最强的马是B,如果存在一种更优的比赛策略,让B的对手不是A,而使得田忌赢更多的钱的话,那么设此时A的对手是b,B的对手是a:
若b>A,则有B>a,b>A。这个结果和B>A,b>a是相同的。
若a<b≤A,则有B>a,b≤A。这个结果不如B>A,b>a来得优秀。
若b≤a≤A,则有B>a,b≤A。这个结果和B>A,b≤a是相同的。
由此可知,交换各自对手后,一定不会使得结果变劣,那么假设是不成立的。
证毕。
第三个贪心策略的证明:
因为田忌最快的马也只是和齐王的马打平,那么田忌只能选择平或输,选择平的话,当然只能用最快的马去平了;选择输的话当时是用最慢的马去输来得值得,这和第一个贪心策略的思路是一样的。
证毕。
我们发现,第三个贪心策略出现了一个分支:打平或输掉。如果穷举所有的情况,算法的复杂度将比求二分图最佳匹配还要高;如果一概而论的选择让最强的马去打平比赛或者是让最差的马去输掉比赛,则存在反例:
光是打平的话,如果齐王马的速度分别是1 2 3,田忌马的速度也是1 2 3,每次选择打平的话,田忌一分钱也得不到,而如果选择先用速度为1的马输给速度为3的马的话,可以赢得200两黄金。
光是输掉的话,如果齐王马的速度分别是1 3,田忌马的速度分别是2 3,田忌一胜一负,仍然一分钱也拿不到。而如果先用速度为3的马去打平的话,可以赢得200两黄金。
虽然因为第三个贪心出现了分支,我们不能直接的按照这种方法来设计出一个完全贪心的方法,但是通过上述的三种贪心策略,我们可以发现,如果齐王的马是按速度排序之后,从高到低被派出的话,田忌一定是将他马按速度排序之后,从两头取马去和齐王的马比赛。有了这个信息之后,动态规划的模型也就出来了!
设f[i,j]表示齐王按从强到弱的顺序出马和田忌进行了i场比赛之后,从“头”取了j匹较强的马,从“尾”取了i-j匹较弱的马,所能够得到的最大盈利。
状态转移方程如下:
f[i,j]=max{f[i-1,j]+g[n-(i-j)+1,i],f[i-1,j-1]+g[j,i]}
其中g[i,j]表示田忌的马和齐王的马分别按照由强到弱的顺序排序之后,田忌的第i匹马和齐王的第j匹马赛跑所能取得的盈利,胜为200,输为-200,平为0。
--------------分割线-----------------------------------------
俩数组 ,排序,l1=1; l2=1; r1=n; r2=n;
( 左向右 如果 a[l1]>b[l2] 则 l1:=l1+1; l2:=l2+1; ans:=ans+200;
右往左 如果 a[r1]>b[r2] 则 r1:=r1-1; r2:=r2-1; ans:=ans+200;
此时如果 a[l1]=b[r2] 则中间的数全相等,不用算了。。
如果 a[l1]<b[r2] 则 s:=s-200; l1:=l1+1; r2:=r2-1;)
继续() 的循环;
证明:
得到从左往右第一个 a[l1]<=b[l2] 和从右往左第一个 a[r1]<=b[r2] 时,
草稿纸上演算一下就知道。。此时不管b[l2]是否等于a[l1] b[r2]是否等于a[r1] 让a[l1]和b[r2] 比赛 总是最好情况之一;
-------------------------rzy------------
稍作简单分析
既可以知道如果自己最强的马打不过齐王的马就派出自己最弱的马
如果打的过的话就去把它灭了
这样一分析,就可以知道 只能从头尾取马
那就转换成了常见的dp的线性模型,类似于矩阵取数的题目了
方程就自然而然的出来了
f[i,j]=max{f[i-1,j]+g[n-(i-j)+1,i],f[i-1,j-1]+g[j,i]}
(小心j=0 和j=i 的情况。。我刚开始就这里挂掉了)
--------------------------------------------
贪心
1.当田忌最慢的马比齐王最慢的马快,赢一场先。因为始终要赢齐王最慢的马,不如用最没用的马来赢它。
2.当田忌最慢的马比齐王最慢的马慢,和齐王最快的马比,输一场。因为田忌最慢的马始终要输的,不如用它来消耗齐王最有用的马。
3.当田忌最慢的和齐王最慢的马慢相等时,分4和5讨论。
4.当田忌最快的马比齐王最快的马快时,赢一场先。因为最快的马的用途就是来赢别人快的马,别人慢的马什么马都能赢。
5.当田忌最快的马比齐王最快的马慢时,拿最慢的马和齐王最快的马比,输一场,因为反正要输一场,不如拿最没用的马输。
6.当田忌最快的马和齐王最快的马相等时,这就要展开讨论了,贪心方法是,拿最慢的马来和齐王最快的马比.
显然是正确的!!!
//--------------------
这里讨论另外一种方程形式:
先排序后肯定从两头取,这个问题上面大神都解释清了(我很弱小解释不能)……
既然从田忌马队两头取,那么可以用一个区间[l,r]表示田忌当前可选的马队,取l或者取r,这样剩下的区间就是[l+1,r]或者[l,r-1]
齐王的马可以利用田忌区间算出来,田忌区间长度是r-l+1,所以赛过n-(r-l+1)场,由此齐王当前的马就是n-(r-l+1)+1=n-r+l
这样方程就有了(递归运行记忆化,别的方法不会……不过应该循环也能写?):
pick(l,r)=max(pick(l+1,r)+g[l,n-r+l],pick(l,r-1)+g[r,n-r+l])
其实原理都差不多来着吧…………只是个人觉得这样好理解些…………
//copy //greedy
#include <cstdio>
#include <algorithm>
using namespace std;
const int M=;
int qt[][M];
int n;
int main()
{
scanf("%d",&n);
for (int i=;i>=;i--)
for (int j=;j<=n;j++)
scanf("%d ",&qt[i][j]);
int s=;
sort(qt[]+,qt[]+n+,[](int a,int b){ return a<b; });
sort(qt[]+,qt[]+n+,[](int a,int b){ return a<b; });
int i1=,i2=n,j1=,j2=n;
while (i1<=i2)
if (qt[][i1]<qt[][j1]) {i1++;j1++;s++;continue;} else
if (qt[][i1]>qt[][j1]) {s--;j1++;i2--;continue;} else
if (qt[][i1]==qt[][j1])
if (qt[][i2]<qt[][j2]) {i2--;j2--;s++;continue;} else {if (qt[][j1]<qt[][i2]) s--;j1++;i2--;continue;}
printf("%d",s*);
return ;
} //dp
#include <iostream>
#include <algorithm>
#include <cstring>
#define N 1005
using namespace std; int n, a[N], b[N];
int f[N][N];
/*
不妨设齐王的马是从快到慢出场的。
f[l][r]: 在田忌的可选区间为[l, r]的时候,能得到的最大奖金,此时已经赛过n - (r - l + 1)场,故此时出场的是齐王的第n - r + l匹马
f[l][r] = max (f[l + 1][r] + g (l, n - r + l), f[l][r - 1] + g (r, n - r + l))
田忌选最快的马 田忌选最慢的马
*/ inline int g (int x, int y)
{
if (a[x] < b[y])
return -;
if (a[x] > b[y])
return ;
return ;
} int work (int l, int r)
{
if (f[l][r] != -)
return f[l][r];
if (l == r)
return f[l][r] = g (l, n); f[l][r] = max (work (l + , r) + g (l, n - r + l), work (l, r - ) + g (r, n - r + l));
return f[l][r];
} bool cmp (int x, int y)
{ return x > y; } int main()
{
cin >> n;
for (int i = ; i <= n; i++)
cin >> a[i];
for (int i = ; i <= n; i++)
cin >> b[i]; sort (a + , a + n + , cmp);
sort (b + , b + n + , cmp);
memset (f, -, sizeof (f)); cout << work (, n) << endl;
return ;
}
tyvj1048 田忌赛马的更多相关文章
- [POJ2287][Tyvj1048]田忌赛马 (贪心+DP)
瞎扯 很经典的一道题 考前才打 我太菜了QAQ 就是先贪心排序了好 然后在DP 这样比直接DP更容易理解 (其实这题做法还有很多) 代码 #include<cstdio> #include ...
- nyoj 364 田忌赛马(贪心)
田忌赛马 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 Here is a famous story in Chinese history. "That ...
- [codevs2181]田忌赛马
[codevs2181]田忌赛马 试题描述 中国古代的历史故事"田忌赛马"是为大家所熟知的.话说齐王和田忌又要赛马了,他们各派出N匹马,每场比赛,输的一方将要给赢的一方200两黄金 ...
- ACM 田忌赛马
田忌赛马 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 Here is a famous story in Chinese history. "That ...
- TYVJ P1048 田忌赛马 Label:dp
描述 中国古代的历史故事“田忌赛马”是为大家所熟知的.话说齐王和田忌又要赛马了,他们各派出N匹马,每场比赛,输的一方将要给赢的一方200两黄金,如果是平局的话,双方都不必拿出钱.现在每匹马的速 ...
- HDUOJ-------1052Tian Ji -- The Horse Racing(田忌赛马)
Tian Ji -- The Horse Racing Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (J ...
- D - D 田忌赛马
D - D 田忌赛马 解题报告 hdu 1052 Tian Ji -- The Horse Racing 链接:http://acm.hust.edu.cn/vjudge/contest/v ...
- HDOJ-1052 田忌赛马(贪心)
田忌赛马 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述: Here is a famous story in Chinese history. "That was ...
- [洛谷P1650] 田忌赛马
贪心难题:总结贪心问题的一般思路 传送门:$>here<$ 题意 田忌和齐王各有n匹马,赛马时一一对应.赢+200,输-200,平+0. 问最多多少钱? 数据范围:$n \leq 2000 ...
随机推荐
- 步骤2:JMeter 分布式测试(性能测试大并发、远程启动解决方案)
转载(记录) http://www.cnblogs.com/fengpingfan/p/5583954.html http://www.cnblogs.com/puresoul/p/4844539.h ...
- 【廖雪峰老师python教程】——OOP
概述 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 数据封装.继承和多态 ...
- C++学习014函数值传递和地址传递
当我们给一个函数传参数的时候,可以直接值传入函数,也给可以把一个地址传入函数 区别就是一个本身不被改变,而另一本身也在改变, 在开发时候都会用到, 这里做下记录 #include <iostre ...
- python 网络编程(socketserver,阻塞,其他方法)
重点回顾: (重点)粘包 : 就是因为接收端不知道如何接收数据,造成接收数据的混乱的问题 只发生在tcp协议上. 因为tcp协议的特点是面向数据流形式的传输 粘包的发生主要是因为tcp协议有两个机制: ...
- visionpro halcon 哪个好
visionpro halcon 哪个好 很多朋友会问到visionpro和halcon这两款机器视觉软件,到底学哪个好呢,今天众寻网就给大家讲一讲: 首先比较下两者的优缺点: halcon: 提供的 ...
- wangEditor编辑器中解析html图文信息问题
在JS中,有一种方法:innerHTML 属性设置或返回表格行的开始和结束标签之间的 HTML. 也就是说,我们可以利用这个属性,把字符串转换为html代码,这样就可以被解析了. 其次,我们是需要在页 ...
- 在网站中配置MIME类型
经常会遇到这样的情况,某种类型的文件不能够正常下载,*.7z,自定义的文件类型等,需要在配置文件里配置后才能正常下载. 打开Web.Config文件: <system.webServer> ...
- ArcGIS Server中创建的两个账户有什么区别
新手常常有这样的疑问: 在安装ArcGIS Server的时候创建的账户和在ArcGIS Server Manager上面创建的账户有什么区别? 解答:前者是是为ArcGIS Server创建的操作系 ...
- PAT 1045 快速排序
https://pintia.cn/problem-sets/994805260223102976/problems/994805278589960192 著名的快速排序算法里有一个经典的划分过程:我 ...
- SSH面试集锦——不看后悔哦!
1. 谈谈你mvc的理解 MVC是Model-View-Controler的简称.即模型-视图-控制器.MVC是一种设计模式,它强制性的把应用程序的输入.处理和输出分开. MVC中的模型 ...