zoukankan      html  css  js  c++  java
  • 田忌赛马 题解

    题目大意

    想必大家都做过一道经典的贪心问题:田忌赛马。
    本题的背景与田忌赛马大致相似:你和对手各有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;
    }
    
  • 相关阅读:
    [转]被玩坏的innerHTML、innerText、textContent和value属性
    在github上优雅的搭建个人博客
    使用jmeter进行压力测试入门讲解
    一、docker 入坑(win10和Ubuntu 安装)
    使用C#开发Android应用之WebApp
    Win10上的Docker应用:Kubernetes(容器集群)
    Win10上的Docker应用:Docker-compose(容器编排)
    Win10上的Docker应用:Hello World
    在web端使用html5访问远程桌面
    HtmlAgilityPack
  • 原文地址:https://www.cnblogs.com/CHK666/p/14955153.html
Copyright © 2011-2022 走看看