Greedy (1) Tian Ji Horse Racing

table of Contents

One, greedy algorithm

1. The nature of greedy choice

2. Optimal substructure properties

Second, Tian Ji horse racing

Three, OJ actual combat

CSU 1722: Race (Tian Ji Horse Racing)

HDU 1338 Game Prediction (Tian Ji Horse Racing)

UVA-1344 HDU-1052 ZOJ-2397 POJ-2287 FZU-1316 OpenJ_Bailian-2287 NBUT-1101 Tian Ji - The Horse Racing


 

One, greedy algorithm

Greedy algorithm, also called greedy algorithm, is an algorithm that finds global optimal solution through local optimal solution. Greedy algorithm can only be used for specific problems.

The problem that can use the greedy algorithm has two characteristics:

1. The nature of greedy choice

The overall optimal solution of a problem can be achieved through a series of local optimal solution choices, and each choice can depend on the choices made before, but not on the choices made later.

2. Optimal substructure properties

When the optimal solution of a problem contains the optimal solution of its sub-problems.

 

 

Second, Tian Ji horse racing

Tian Ji's horse racing comes from "Historical Records". Sun Binxian was inferior to King Ziwei's superior horse. Tian Ji lost the first game. In the second game, Sun Bin won a round with the superior horse Qiwei Wang's medium horse. In the third game, Sun Bin took the middle horse to Qiwei Wang's inferior horse and defeated another game. The result of the game was two wins in three games, and Tian Ji defeated King Qi Wei. It was the same horse, but because of a change in the order of appearance of the game, the result was turned from defeat to victory.

 

Three, OJ actual combat

CSU 1722: Race (Tian Ji Horse Racing)

topic:

Description

Johnson and Bob are crazy motorcycle collecting enthusiasts. In order to prove their own motorcycles is the best, they issued a challenge to each other. Johnson wants to win the challenge.As a good friend of Johnson’s, you need to give advice to Johnson. Johnson and Bob each can select their best n motorcycles. And each motorcycle has a value v. There are n matches in total. Any motorcycle can be chosen optionally to participate in the match(but each motorcycle can only participate once). Each time the motorcycle with high value will win. Johnson gets the order of Bob’s motorcycles in advance. Can you help Johnson arrange the competition order of motorcycles in order to win the most of the matches?

Input

First line input an integer T(mean there are T cases)
In each case , first line input an integer n (mean there are n motorcycles) (0<n<=10000)
Next line input n integers (mean the value of Johnson’s n motorcycles)
Next line n integers (mean the value of Bob’s n motorcycles )

Output

Every case output an integer mean the most match can win.

Sample Input

1
5
6 4 5 1 3
8 9 3 4 7

Sample Output

2

The main idea of ​​the question is that there are two people, Johnson and Bob. The first input is Johnson's, and he knows the order of Bob's numbers.
Now let Johnson arrange his own order, 1 to 1 PK, to make the most wins.
This problem is equivalent to Johnson being able to control the number of appearances of two players. In this case, it is done with greed.
The specific greedy strategy is that very simple while loop.
Of course, it must be sorted first.

Code:

#include<iostream>
#include<algorithm>
using namespace std;
 
int main()
{
    int n;
    cin >> n;
    int t;
    while (n--)
    {
        cin >> t;
        int *a = new int[t];
        int *b = new int[t];
        for (int i = 0; i < t; i++)cin >> a[i];
        for (int i = 0; i < t; i++)cin >> b[i];
        sort(a, a + t);
        sort(b, b + t);
        int i = 0, j = 0;
        int sum = 0;
        while (i < t && j < t)
        {
            if (a[i]>b[j])
            {
                sum++;
                j++;
            }
            i++;
        }
        cout << sum << endl;
    }
    return 0;
}

HDU 1338 Game Prediction (Tian Ji Horse Racing)

 

topic:

Description

Suppose there are M people, including you, playing a special card game. At the beginning, each player receives N cards. The pip of a card is a positive integer which is at most N*M. And there are no two cards with the same pip. During a round, each player chooses one card to compare with others. The player whose card with the biggest pip wins the round, and then the next round begins. After N rounds, when all the cards of each player have been chosen, the player who has won the most rounds is the winner of the game. 
Given your cards received at the beginning, write a program to tell the maximal number of rounds that you may at least win during the whole game. 

Input

The input consists of several test cases. The first line of each case contains two integers m (2 <= m <= 20) and n (1 <= n <= 50), representing the number of players and the number of cards each player receives at the beginning of the game, respectively. This followed by a line with n positive integers, representing the pips of cards you received at the beginning. Then a blank line follows to separate the cases. 

The input is terminated by a line with two zeros. 

Output

For each test case, output a line consisting of the test case number followed by the number of rounds you will at least win during the game. 

Sample Input

2 5
1 7 2 10 9

6 11
62 63 54 66 65 61 57 56 50 53 48

0 0

Sample Output

Case 1: 2
Case 2: 4

This question is actually asking how many games we can win if everyone else uses the best strategy.

First of all, how those people's cards are distributed has no effect on our results.

It can be considered equivalently, all the remaining cards are in the hands of one person, n games, each time he plays 1 card, I play 1 card, and ask me how many games I can win at least.

Secondly, this is a Tian Ji horse racing problem.

Because it requires me to win at least the number of rounds, this is completely equivalent to a completely transparent game, that is, he knows what card I want to play each time.

Furthermore, this is equivalent to directly playing cards in descending order. He knows this and knows how much I want to play each time.

So he would use Tian Ji's horse racing strategy to suppress me.

His strategy, to be specific, is that every time I see if I can win, I will play the biggest card to win me, and if I can't, I will play the smallest card and lose in a cool manner.

Hereinafter referred to as big and small cards (you only need to divide his cards into 2 categories, and you don’t need to know how many they are)

Of course, when calculating this question, we don’t need to figure out the cards he played every time, we only need a variable, fail.

Fail means that I have lost a few games, which means that he has played a few big cards before then, so fail is initialized to 0.

Let me explain the winning and losing indicators: i + list[i] + fail <m*n

In the ith round (starting from the 0th round), I played list[i], he has already failed a big hand, these big hands are bigger than list[i]

Please note that although the reasoning here uses the assumption that I play cards in order, this assumption is still general and accurate answers can still be obtained.

Now I need to judge whether he still has a card larger than list[i]. If there is, then I lose the i-th game, fail++

How to judge?

Get rid of the i card that I have already played, and the big fail card, the biggest card left is m*ni-fail

If list[i] is this card, then I am the biggest and I win. If list[i] is smaller than this card, then this card must still be in his hand and I lose.

caution! ! ! I'm very strict! ! !

It must be noted that the small cards are not necessarily smaller than list[i], maybe some of my cards are relatively small, and in the end my cards are smaller than some of his small cards.

This situation is very likely to exist, but it does not affect all of my above statements, nor does it affect the complete correctness of the code below. Please distinguish this by yourself.

Code:

#include<iostream>
#include<algorithm>
using namespace std;
 
int list[51];
bool cmp(int a, int b)
{
	return a > b;
}
 
int main()
{
	int m, n, fail, cas = 1;
	while (scanf("%d%d", &m, &n))
	{
		if (m == 0 && n == 0)break;
		for (int i = 0; i < n; i++)scanf("%d", &list[i]);
		sort(list, list + n, cmp);
		fail = 0;
		for (int i = 0; i < n; i++)if (i + list[i] + fail < m*n)fail++;
		printf("Case %d: %d\n", cas++, n - fail);
	}
	return 0;
}

0ms AC

UVA-1344 HDU-1052 ZOJ-2397 POJ-2287 FZU-1316 OpenJ_Bailian-2287 NBUT-1101 Tian Ji - The Horse Racing

There is a very similar topic, CSU 1722: Race (Tian Ji horse racing)

The question on CSU only seeks the maximum number of wins, and does not distinguish between losses and draws, so it is relatively simple.

And this question does not deduct points for a tie, and points for a loss, so it is more complicated.

topic:

Description

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.

Input

The input consists of up to 50 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. The input ends with a line that has a single `0' after the last test case.

Output

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

Sample Input

3
92 83 71
95 87 74
2
20 20
20 20
2
20 19
22 18
0

Sample Output

200
0
0

The key to this topic is to clarify your thinking and find the perfect greedy strategy.

Theorem 1: If Tian Ji’s minimum number is smaller than Qi Wang’s minimum number, then use Tian Ji’s minimum number and Qi Wang’s maximum number to play against each other. If you lose 1 round, the two sides change from n to n-1, and you must pass Seek the optimal solution of this sub-problem to obtain the optimal solution of the n problem.

Theorem 2: If Tian Ji’s smallest number is greater than Qi Wang’s smallest number, then use Tian Ji’s smallest number and Qi Wang’s smallest number to win 1 round, and the two sides will change from n to n-1, and they must pass Seek the optimal solution of this sub-problem to obtain the optimal solution of the n problem.

Theorem 3: If Tian Ji’s maximum number is smaller than Qi Wang’s maximum number, then use Tian Ji’s minimum number and Qi Wang’s maximum number to play against each other. If you lose 1 round, the two sides will change from n to n-1, and you must pass Seek the optimal solution of this sub-problem to obtain the optimal solution of the n problem.

Theorem 4: If Tian Ji’s maximum number is greater than Qi Wang’s maximum number, then use Tian Ji’s maximum number and Qi Wang’s maximum number to play against each other. If you win 1 round, the two sides change from n to n-1, and you must pass Seek the optimal solution of this sub-problem to obtain the optimal solution of the n problem.

Theorem 5: If Tian Ji’s minimum number is the same as Qi Wang’s minimum number, and Tian Ji’s maximum number is the same as Qi Wang’s maximum number, then use Tian Ji’s minimum number and Qi Wang’s maximum number to play against each other, and the two sides will change from n to n-1, the optimal solution of n problem can be obtained by seeking the optimal solution of this sub-problem.

Note that in Theorem 5, Tian Ji will not necessarily lose this round.

Theorems One and Two and Theorems Three and Four are independent. In other words, if Tian Ji’s smallest number is smaller than Qi Wang’s smallest number, and the largest number is greater than Qi Wang’s largest number,

Then whether you use Tian Ji's minimum number or maximum number to fight against Qi Wang's maximum number, you can get the optimal solution.

All situations can be divided into at least one of these five types, so the strategy is clear.

Because the strategies in Theorem 3 and Theorem 5 are actually the same, the codes are combined. The code is only divided into 4 categories.

Although the strategy in Theorem 1 is the same, but if you don't want to write the classification too strange, there is no merger.

Code:

#include<iostream>
#include<algorithm>
using namespace std;

int a[1000];
int b[1000];

int main()
{
	int n;
	while (cin >> n)
	{
		if (n == 0)break;
		for (int i = 0; i < n; i++)cin >> a[i];
		for (int i = 0; i < n; i++)cin >> b[i];
		sort(a, a + n);
		sort(b, b + n);
		int lowa = 0, lowb = 0, higha = n - 1, highb = n - 1, sum = 0;
		while (lowa <= higha)
		{
			if (a[lowa] < b[lowb])
			{
				lowa++;
				highb--;
				sum--;
			}
			else if (a[lowa]>b[lowb])
			{
				lowa++;
				lowb++;
				sum++;
			}
			else
			{
				if (a[higha]>b[highb])
				{
					higha--;
					highb--;
					sum++;
				}
				else
				{
					sum -= (a[lowa] < b[highb]);
					lowa++;
					highb--;
				}
			}
		}
		cout << sum * 200 << endl;
	}
	return 0;
}

 

Guess you like

Origin blog.csdn.net/nameofcsdn/article/details/112425560