HDU1052 Tian Ji -- The Horse Racing

本文探讨了经典的田忌赛马问题,通过贪心算法来确定最佳的比赛策略,以最大化田忌的收益。文章详细解释了如何通过排序和比较双方马匹的速度来决定比赛配对,并提供了具体的代码实现。

题目描述

田忌赛马问题,田忌和王都有n匹马。n场比赛(每匹马都只能上场一次)。每场比赛输的要给赢的人200块钱,问最后田忌最多能获得多少钱。

输入n,接着是n匹田忌马速度,接着是n匹王的马速度,遇0结束。

样例

输入

3

92 83 71

95 87 74

2

20 20

20 20

2

20 19

22 18

0

输出

200

0

0


思路:显然为贪心问题。先要将田忌和王的马排序,从最慢的两匹马下手考虑。

A.若两匹最慢的马中田忌的马慢,不难知道田忌这匹马是所有马中最慢的。那不妨破罐破摔,那它去和王最快的马比,给队友多一点机会。

B.若两匹最慢的马中田忌的马快,那也不难知道田忌所有的马都比王这匹马快。那肯定是让最弱的马去比它,保留实力。

C.Here comes the question…………两匹最慢的马一样快怎么办?让他们打平?让田忌的最慢的马去消耗王最快的马?

很遗憾,都不是。在田忌1 2 王1 3这组数据下,显然不能简单让他们打平(-200)。这样不如去消耗王最快的马(0)。

而在田忌1 3 王 1 2 这组数据下,又不能简单去消耗王最快的马(0)这样不如让他们打平(200)。

那么看来,我们需要分类讨论。

a.田忌的快马比王的快马快。那么不难看出田忌的快马是所有马中最快的,那么肯定要让他赢王最快的马,给队友赢得机会。

b.田忌的快马比王的快马慢。那么王的快马是所有马中最快的。既然田忌的马没有比它快的,不妨让最慢的去消耗它,给队友赢得机会。

c.田忌的快马和王的快马一样快时,这时最慢的马和最快的马两人都一样快。这里我们选择让田忌的慢马去消耗王的快马。因为这样可以为队友留下最多的机会。虽然输了一场,但是至少可以让剩下的队友多赢一场(仔细理解)。


不难看出,以上的算法是贪心的。

另外,我觉得值得回味的是用了模拟指针。下面放代码。


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int tian[1000],king[1000];
int main()
{
	int n;
	while(scanf("%d",&n) && n){
		int cnt = 0;//记录田忌的胜负结果
		memset(tian,0,sizeof(tian));
		memset(king,0,sizeof(king));
		for(int i = 0 ; i < n ; i ++) scanf("%d",&tian[i]);
		for(int i = 0 ; i < n ; i ++) scanf("%d",&king[i]);
		sort(tian,tian+n);
		sort(king,king+n);
		int pt1 = 0 , pt2 = n-1, pk1 = 0, pk2 = n-1;//模拟指针
		while(pt1 < pt2 && pk1 < pk2){
			if(tian[pt1] < king[pk1]){//A情况 田忌慢马<王慢马
				pt1++;
				pk2--;
				cnt--;
			}else if(tian[pt1] > king[pk1]){//B情况 田忌慢马>王慢马
				pt1++;
				pk1++;
				cnt++;
			}else{//C情况 田忌慢马=王慢马
				if(tian[pt2] > king[pk2]){//C.a情况
					pt2--;
					pk2--;
					cnt++;
				}else if(tian[pt2] < king[pk2]){//C.b情况
					pt1++;
					pk2--;
					cnt--;
				}else{           //C.c情况 最快和最慢的马都相等 
					if(tian[pt1] == tian[pt2]){
						break;//如果这时发现田忌的所有马速度都一样,那么就不要比了,因为下面都是平局
					}else{
						pt1++;
						pk2--;
						cnt--;
					}
				}
			}
		}
		if(tian[pt1] < king[pk1]) cnt--;//最后还留下了一对马,比一下吧
		if(tian[pt1] > king[pk1]) cnt++;
		printf("%d\n",cnt*200);
	}
	return 0;
}


计及风电并网运行的微电网及集群电动汽车综合需求侧响应的优化调度策略研究(Matlab代码实现)内容概要:本文研究了计及风电并网运行的微电网及集群电动汽车综合需求侧响应的优化调度策略,并提供了基于Matlab的代码实现。研究聚焦于在高渗透率可再生能源接入背景下,如何协调微电网内部分布式电源、储能系统与大规模电动汽车充电负荷之间的互动关系,通过引入需求侧响应机制,建立多目标优化调度模型,实现系统运行成本最小化、可再生能源消纳最大化以及电网负荷曲线的削峰填谷。文中详细阐述了风电出力不确定性处理、电动汽车集群充放电行为建模、电价型与激励型需求响应机制设计以及优化求解算法的应用。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事新能源、微电网、电动汽车等领域技术研发的工程师。; 使用场景及目标:①用于复现相关硕士论文研究成果,深入理解含高比例风电的微电网优化调度建模方法;②为开展电动汽车参与电网互动(V2G)、需求侧响应等课题提供仿真平台和技术参考;③适用于电力系统优化、能源互联网、综合能源系统等相关领域的教学与科研项目开发。; 阅读建议:建议读者结合文中提供的Matlab代码进行实践操作,重点关注模型构建逻辑与算法实现细节,同时可参考文档中提及的其他相关案例(如储能优化、负荷预测等),以拓宽研究视野并促进交叉创新。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值