(贪心 说人话)田忌赛马 基础->洛谷P1650 进阶

一 简单田忌赛马

田忌赛马 描述
田忌和齐王各自都有N匹马 每一匹马都有一个速度值(速度值为正整数 数值越大表示马跑得越快) 双方约定:
1每一轮比赛 双方各自出一匹马对决 每一匹马只能出场一次
2谁的马速度快谁就获胜
3速度相等则平局
请你设计策略 让田忌尽可能赢更多的比赛 最终输出田忌能赢的最大胜场数
输入格式
第一行输入一个整数 N(1 ≤ N ≤ 10^5)表示双方马匹的数量
第二行输入 N 个整数 表示田忌的 N 匹马的速度值(用空格分隔)
第三行输入 N 个整数 表示齐王的 N 匹马的速度值(用空格分隔)
输出格式
输出一个整数,表示田忌能赢的最大胜场数

1基本策略

我想让田忌能赢得最多
先排序 从大到小
四个指针int型
指向
-------田忌最大的马 ------田忌最小的马
-------齐王最大的马 ------齐王最小的马
(其实排序后 每一个数组的0 N-1 0 N-1位置)
让田忌最大的马 和 齐王最大的马比较
如果能赢 直接上场
如果不能赢 反正怎么样都不可能赢了 就用田忌最小的 马去和齐王最大的马 上场比赛 比赛一定会输 但是浪费的是田忌最小的马 浪费的最小化了

2我的代码(求指点)

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
	int N;
	cin>>N;
	vector<int>tian(N);
	vector<int>qi(N);
	for(int i=0;i<N;++i)cin>>tian[i];
	for(int i=0;i<N;++i)cin>>qi[i];
	sort(tian.begin(),tian.end(),greater<int>() );
	sort(qi.begin(),qi.end(),greater<int>() );
	int  t_fast=0,t_slow=N-1;
	int q_fast=0,q_slow=N-1;
	int winCnt=0;
	while(t_fast<=t_slow){
		if(tian[t_fast] > qi[q_fast] ){//田忌能赢 就直接赢
			t_fast++;
			q_fast++;
			winCnt++; 
		}else{	
		//当田忌最快的马 < 齐王最快的马 这时候一定不会赢 平局和输是一个效果:都不会winCnt++
		// 所以直接让田忌最小的马去消耗齐王最大的马 即可
			t_slow--;
			q_fast++;
		}
	} 
	//输出赢的次数
	cout<<winCnt<<endl;
} 

二 洛谷 进阶P1650 田忌赛马

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

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

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

输入格式

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

输出格式

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

输入输出样例 #1

输入 #1

3
92 83 71
95 87 74

输出 #1

200

数据规模与约定

  • 对于 20%20\%20% 的数据,1≤N≤651\le N\le 651N65
  • 对于 40%40\%40% 的数据,1≤N≤2501\le N\le 2501N250
  • 对于 100%100\%100% 的数据,1≤N≤20001\le N\le20001N2000

1我的代码

//AC了
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
	int N;
	cin>>N;
	vector<int>tian(N);
	vector<int>qi(N);
	for(int i=0;i<N;++i)cin>>tian[i];
	for(int i=0;i<N;++i)cin>>qi[i];
	sort(tian.begin(),tian.end(),greater<int>() );
	sort(qi.begin(),qi.end(),greater<int>() );
	int  t_fast=0,t_slow=N-1;
	int q_fast=0,q_slow=N-1;
	int res=0;
	while(t_fast<=t_slow){
		if(tian[t_fast] > qi[q_fast] ){
            res+=200;
			t_fast++;
			q_fast++;
		}else if(tian[t_fast] < qi[q_fast] ){
			t_slow--;
			q_fast++;
            res-=200;
		}else if(tian[t_fast]==qi[q_fast] ){
			if(tian[t_slow] > qi[q_slow] ){
				t_slow--;
				q_slow--;
				res+=200; 
			}else{
				if(tian[t_slow] < qi[q_fast] ){
					res-=200;
				}
				t_slow--;
				q_fast++;
				
			}
		}
	} 
	//
	cout<<res<<endl;
} 

这个代码AC了

4ms/788.00KB
AC
#1
Accepted, 得分 10.ok accepted
5ms/1.04MB
AC
#2
Accepted, 得分 10.ok accepted
4ms/788.00KB
AC
#3
Accepted, 得分 10.ok accepted
4ms/788.00KB
AC
#4
Accepted, 得分 10.ok accepted
5ms/788.00KB
AC
#5
Accepted, 得分 10.ok accepted
4ms/788.00KB
AC
#6
Accepted, 得分 10.ok accepted
4ms/788.00KB
AC
#7
Accepted, 得分 10.ok accepted
4ms/788.00KB
AC
#8
Accepted, 得分 10.ok accepted
4ms/816.00KB
AC
#9
Accepted, 得分 10.ok accepted
5ms/808.00KB
AC
#10
Accepted, 得分 10.ok accepted

三 这两题核心要点

先说第一题

第一题
if 田忌t_fast > 齐王q_fast 直接比赛winCnt+1
if 田忌t_fast < 齐王q_fast 一定会winCnt不变 反正不管怎么样都会输 就让田忌t_slow 去消耗齐王q_fast
if 田忌t_fast齐王q_fast 一定winCnt不变 反正怎么样都不会winCnt++ 就直接让田忌t_slow 去消耗齐王q_fast
< 和
可以合并再一起

再说第二题

if 田忌t_fast > 齐王q_fast 直接比赛res+200
if 田忌t_fast < 齐王q_fast 反正不管怎么样都会输 就让田忌t_slow 去消耗齐王q_fast res-200
if 田忌t_ fast == 齐王q_fast 细说
如果田忌最快 == 齐王最快,不能直接送掉,要判断田忌最慢能否吃掉齐王最慢
如果能 → 就让最慢打最慢(+200)
不能 → 才让最慢打最快

自己的碎碎念 (随便写)

//纪念一下自己这几个月的努力
//已经得偿所愿了 转到计算机了
//接下来会继续坚持学习算法
//one can walk for alone
在这里插入图片描述
//机考那天做的题
在这里插入图片描述
//有几道实在WA
//啊啊啊
在这里插入图片描述

//当时刷PTA建的文件夹
//知道要靠PTA就反复刷
//温故而知新
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
//PTA刷透就开始刷leetcode了
//leetcode只刷了大概100道
//嫌丢人 太菜了 就不展示图片了
//哈哈哈

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值