田忌赛马贪心算法_贪心算法--田忌赛马

这是一篇关于田忌赛马问题的文章,通过贪心算法解决如何在马匹速度已知的情况下,赢得最多比赛的问题。文章介绍了算法思路,并提供了Java代码实现。在每一轮比赛中,田忌的马匹会与国王的马匹进行匹配,目标是最大化赢得的比赛数量,这可以转化为寻找最大匹配问题。对于速度确定的马匹,可以直接应用贪心策略来解决。给出的代码示例展示了如何找到最优策略并计算可以获得的最大银元数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

田忌赛马

时间限制:3000 ms  |  内存限制:65535 KB

难度:3

描述

Here is a famous story in Chinese history.

“That was about 2300 years ago. General Tian Ji was a high official in the country Qi. He likes to play horse racing with the king and others.”

“Both of Tian and the king have three horses in different classes, namely, regular, plus, and super. The rule is to have three rounds in a match; each of the horses must be used in one round. The winner of a single round takes two hundred silver dollars from the loser.”

“Being the most powerful man in the country, the king has so nice horses that in each class his horse is better than Tian’s. As a result, each time the king takes six hundred silver dollars from Tian.”

“Tian Ji was not happy about that, until he met Sun Bin, one of the most famous generals in Chinese history. Using a little trick due to Sun, Tian Ji brought home two hundred silver dollars and such a grace in the next match.”

“It was a rather simple trick. Using his regular class horse race against the super class from the king, they will certainly lose that round. But then his plus beat the king’s regular, and his super beat the king’s plus. What a simple trick. And how do you think of Tian Ji, the high ranked official in China?”

Were Tian Ji lives in nowadays, he will certainly laugh at himself. Even more, were he sitting in the ACM contest right now, he may discover that the horse racing problem can be simply viewed as finding the maximum matching in a bipartite graph. Draw Tian’s horses on one side, and the king’s horses on the other. Whenever one of Tian’s horses can beat one from the king, we draw an edge between them, meaning we wish to establish this pair. Then, the problem of winning as many rounds as possible is just to find the maximum matching in this graph. If there are ties, the problem becomes more complicated, he needs to assign weights 0, 1, or -1 to all the possible edges, and find a maximum weighted perfect matching…

However, the horse racing problem is a very special case of bipartite matching. The graph is decided by the speed of the horses — a vertex of higher speed always beat a vertex of lower speed. In this case, the weighted bipartite matching algorithm is a too advanced tool to deal with the problem.

In this problem, you are asked to write a program to solve this special case of matching problem.

输入

The input consists of many test cases. Each case starts with a positive integer n (n <= 1000) on the first line, which is the number of horses on each side. The next n integers on the second line are the speeds of Tian’s horses. Then the next n integers on the third line are the speeds of the king’s horses.

输出

For each input case, output a line containing a single number, which is the maximum money Tian Ji will get, in silver dollars.

样例输入

3

92 83 71

95 87 74

2

20 20

20 20

2

20 19

22 18

样例输出

200

0

0

一本ACM书上面的一道原题,照着书上敲的居然没有AC,那本书出的确实不太好。

import java.util.Scanner;

public class T12田忌赛马 {

public static void main(String[] args) {

Scanner sc=new Scanner(System.in);

while(sc.hasNext()){

int n=sc.nextInt();

int[] tian=new int[n];

int[] qi=new int[n];

for (int i = 0; i < tian.length; i++) {

tian[i]=sc.nextInt();

}

for (int i = 0; i < qi.length; i++) {

qi[i]=sc.nextInt();

}

for (int i = 0; i < qi.length; i++) {

for (int j = 0; j < qi.length; j++) {

if(tian[i]>tian[j]){

int t=tian[i];

tian[i]=tian[j];

tian[j]=t;

}

if(qi[i]>qi[j]){

int t=qi[i];

qi[i]=qi[j];

qi[j]=t;

}

}

}

int l1=0,l2=0,r1=n-1,r2=n-1,ans=0;

while(l1<=r1){

if(tian[l1]>qi[l2]){

ans+=200;

l1++;

l2++;

}

else if(tian[l1]

ans-=200;

r1--;

l2++;

}

else if(tian[l1]==qi[l2]&&tian[r1]>qi[r2]){

ans+=200;

r1--;

r2--;

}

else if(tian[l1]==qi[l2]&&tian[r1]

if(tian[r1]

ans-=200;

}

r1--;

l2++;

}

else if(tian[l1]==qi[l2]&&tian[r1]==qi[r2]){

r1--;

l1++;

}

}

System.out.println(ans);

}

}

}

<think>好的,我需要帮助用户找到田忌赛马问题在C语言中使用贪心算法的实现。首先,我得回忆一下田忌赛马的基本情况和贪心算法的应用方式。 田忌赛马的故事中,田忌通过合理安排马的出场顺序,以弱胜强。贪心算法在这里通常用于每一步选择最优策略,比如用最差的马消耗对方最强的,或者用最好的马尽可能赢比赛。用户需要的是C语言的实现,所以得考虑如何将这种策略转化为代码。 接下来,我需要确保解决方案符合贪心算法的核心步骤。通常包括:排序双方的马匹,然后比较马匹的速度,选择最优的对阵方式。这里可能会有不同的策略,比如田忌的最快马如果比齐王的最快马快,就直接赢;否则用最慢的马去消耗对方的最快马,以保存实力。 然后,我得考虑C语言的具体实现。需要将双方的马排序,然后使用双指针来遍历比较。例如,使用两个数组分别代表田忌和齐王的马,排序后,用两个指针分别指向当前最快和最慢的马,根据情况决定如何匹配。 还需要注意代码的结构,比如输入处理、排序函数的使用,以及胜负条件的判断。例如,在C语言中可以使用qsort函数来排序数组,然后使用while循环和指针移动来遍历数组。 同时,我需要检查代码的正确性,比如排序是否正确,指针移动是否合理,以及得分计算是否符合逻辑。例如,当田忌的慢马输给齐王的快马时,是否正确地减少了损失,或者当平局时如何处理。 可能遇到的问题包括如何处理平局的情况,是否应该让平局的情况保留到后续比较,或者直接跳过。不同的策略可能导致不同的结果,需要确保代码逻辑与所选贪心策略一致。 最后,我需要验证代码的正确性,比如通过示例输入,如田忌的马速度为[3, 5, 7],齐王的为[2, 6, 8],预期输出应为1,即田忌赢一场,输一场,平一场,总分200。这时候代码是否能正确计算得分。 另外,用户可能需要相关的问题,比如贪心策略的选择理由、时间复杂度分析、优化方法等,需要准备这些问题以供用户进一步学习。</think>### 田忌赛马贪心算法C语言实现 #### 问题分析 田忌赛马问题要求通过合理安排马匹对阵顺序,最大化比赛得分。贪心策略核心思想: 1. 用最差的马消耗对方最强的马(保存实力) 2. 用最好的马尽可能赢得比赛 #### 算法步骤 1. 将田忌和齐王的马速分别升序排序 2. 设置四个指针比较最优/最劣马匹 3. 分三种情况处理最优对阵策略 #### C语言实现代码 ```c #include <stdio.h> #include <stdlib.h> int compare(const void *a, const void *b) { return *(int*)a - *(int*)b; } int tianji_race(int tian[], int qi[], int n) { qsort(tian, n, sizeof(int), compare); qsort(qi, n, sizeof(int), compare); int t_slow = 0, t_fast = n-1; int q_slow = 0, q_fast = n-1; int score = 0; while (t_slow <= t_fast) { if (tian[t_fast] > qi[q_fast]) { // 田忌快马能赢 score += 200; t_fast--; q_fast--; } else if (tian[t_slow] > qi[q_slow]) { // 田忌慢马能赢 score += 200; t_slow++; q_slow++; } else { // 用最差马消耗对方最优马 if (tian[t_slow] < qi[q_fast]) score -= 200; t_slow++; q_fast--; } } return score; } int main() { int n = 3; int tian[] = {3, 5, 7}; int qi[] = {2, 6, 8}; printf("最终得分: %d\n", tianji_race(tian, qi, n)); // 输出200 return 0; } ``` #### 代码解析 1. **排序处理**:使用`qsort`对双方马匹升序排列,时间复杂度$O(n \log n)$ 2. **双指针策略**: - `t_fast`和`q_fast`指向当前最快马 - `t_slow`和`q_slow`指向当前最慢马 3. **核心逻辑**: - 优先用快马赢快马(当田忌快马更强时) - 次选用慢马赢慢马(当田忌慢马更强时) - 最后用最差马消耗对方最优马(减少损失) #### 性能指标 - 时间复杂度:$O(n \log n)$(主要来自排序过程) - 空间复杂度:$O(1)$(原地操作) [^1]: 该实现参考了贪心算法在最优匹配问题中的通用解法思路
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值