ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

田忌赛马 题解

2021-06-30 16:34:21  阅读:213  来源: 互联网

标签:田忌赛马 int 题解 胜场 tot k2 5050 贪心


题目大意

想必大家都做过一道经典的贪心问题:田忌赛马。
本题的背景与田忌赛马大致相似:你和对手各有n匹马,每匹马都有一个能力值,你和对手每轮选择一匹自己的未上场的马进行比赛,当你的马的能力值大于对方时,你获得这轮的胜利。
你已知对手每匹马的出场顺序,如何安排你的马的出场顺序,使得自己的胜场最多?
与传统的贪心题不同的地方是,这次你希望在胜场最多的情况下,给出字典序最大的出场顺序(能力值的字典序)。

解题思路

首先,我们要对两个数组排序(b数组的顺序无所谓,不过a数组得存在另一个数组里排序,毕竟a的顺序是很有用的)
接着,我们要运用贪心的方法求出最多的胜场。
然后,我们for循环枚举当前PK的马,随后贪心求解
我们贪心的思想就是让小的去对掉大的,但是我们的代码中并没有明显的这一步。
因为如果当前没有任何一匹马能战胜这匹马,我们的判断就会起作用:如果这匹马不在最大成功匹配中,tot就不会减1
这样就会符合胜场最多的条件,同时字典序最大。

代码

#include<bits/stdc++.h>
using namespace std;
int n,k1,k2,k3,tot,a[5050],b[5050],c[5050],bb[5050],cc[5050],v[5050];
bool cmp(int x,int y){return x>y;}
int main()
{
//	freopen("horse.in","r",stdin);
//	freopen("horse.out","w",stdout);
	scanf("%d",&n); 
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
		c[i]=a[i];
	for(int i=1;i<=n;i++)
		scanf("%d",&b[i]);
	sort(c+1,c+n+1,cmp);//从大到小排列敌方的马的能力值 
	sort(b+1,b+n+1,cmp);//从大到小排列你的马的能力值 
	for(int i=1,j=1;i<=n&&j<=n;j++)//贪心求出最大赢的场数,用tot记录 
		if(b[i]>c[j])i++,tot++;
	for(int i=1;i<=n;i++)//枚举PK第几头马 
	{
		memset(v,0,sizeof(v));
		k2=k3=0;//清空 
		//k2:是否赢了敌方的马 
		//k3统计的是当前最大的成功匹配数 
		for(int j=1;j<=n;j++)
			if(c[j]==a[i]&&!cc[j]){cc[j]=1;break;}
		//cc[j]=1表示c[j]在前i个a中出现过 
		//v[j]表示最大的成功中有没有第j个数 
		for(int j=n,k=n;j&&k;j--)
		{
			if(bb[j])continue;//这个位有没有用过 
			while(k&&cc[k])k--;//前面出现过c[j],直接跳过 
			if(k&&b[j]>c[k])k--,v[j]=1,k3++;
		}
		bool f=1;
		//f表示的应该是是否要去掉当前这个匹配 
		for(int j=1;j<=n;j++)//贪心从大到小枚举 
		{
			if(!bb[j])//没有被用过 
			{
				if(b[j]>a[i])k2=1;//可以杀死敌方的马 
				if(!v[j])f=0;//没有在最大成功匹配中,不用删掉 
				if(k2+k3==tot+f)//选择这个数后面的答案是否正确 
				{
					printf("%d ",b[j]);//输出答案 
					bb[j]=1;//标记成已使用 
					tot-=k2;//让tot减去这轮的情况 
					break;//直接跳出循环 
				}
			}
		}
	}
	return 0;
}

标签:田忌赛马,int,题解,胜场,tot,k2,5050,贪心
来源: https://www.cnblogs.com/CHK666/p/14955153.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有