HDU hdu 1052 Tian Ji -- The Horse Racing 贪心算法

这个题使用贪心算法来解决。

解决问题的基本步骤:

1、如果田忌最快的马比齐王最快的马快,则比之

2、如果田忌最快的马比齐王最快的马慢,则用田最慢的马跟齐最快的马比  //这是贪心的第一步

3、如果田忌最快的马的速度与齐威王最快的马速度相等

3.1、如果田忌最慢的比齐威王最慢的快,则比之                              //这是贪心的第二步

3.2、如果田忌最慢的比齐威王最慢的慢,田忌慢VS齐王快

3.3、田忌最慢的与齐威王最慢的相等,田忌慢VS齐王快

总体贪心策略分析:

我们要知道一个原则,那就是如果能赢的话,尽量用一个劣马消耗掉这个马。  首先,如果ji最快的马 > king最快的时候,可以直接比掉; 如果ji最快的马<king最快的时候,则用ji最慢的马将king最快的比掉; 但是,如果当ji最快==king最快的时候,这时不能直接用劣马比掉快马,因为要考虑如何才能使这个最劣马发挥最大价值。如果ji最劣马>king最劣马的时候,可以比掉(此时更有价值);当ji最劣马<=king劣马时,可以直接用ji最劣马比掉king快马,但这里要注意考虑ji劣马和king快马的大小关系,来确定是否要sum-=200(程序1就是这里没有考虑到)。

下面的代码时间超时,因为使用了对Integer排序:

import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeMap;
class MyComparator implements Comparator<Integer> {
    public int compare(Integer o1, Integer o2) {
        return o2 - o1;
    }
}
public class Main {
	// 贪心算法解决问题的思路
	public static void main(String[] args) {
		int n;
		Scanner in = new Scanner(System.in);
		n = in.nextInt();
		while (n != 0) {
			Integer[] A = new Integer[n];
			Integer[] B = new Integer[n];
			for(int i=0;i<n;i++){
				A[i]=in.nextInt();
			}
			for(int i=0;i<n;i++){
				B[i]=in.nextInt();
			}
			Arrays.sort(A,new MyComparator());
			Arrays.sort(B,new MyComparator());
			int i,k=n-1;
			int j,f=n-1;
			int ji=0; //用来记录比较的次数,以跳出循环
			int sum = 0;
			i=j=0;
			while(ji!=n){
				if(A[i]>B[j]) {i++; j++; ji++; sum+=200; continue;}   
				if(A[i]<B[j]) {k--; j++; ji++; sum-=200; continue;}
				if(A[i]==B[j]){
					if(A[k]>B[f]){k--; f--; ji++; sum+=200;continue;}
					if(A[k]<B[f]){k--; j++; ji++; sum-=200;continue;}   //这里错了,要比较A[k]<B[j]?
					if(A[k]==B[f]){k--; j++; ji++; continue;}
				}
			}
			System.out.println(sum);
			n = in.nextInt();
		}
	}
}


最后通过的代码:

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeMap;
public class Main {
	// 贪心算法解决问题的思路
	public static void main(String[] args) {
		int n;
		Scanner in = new Scanner(System.in);
		n = in.nextInt();
		while (n != 0) {
			int[] A = new int[n];
			int[] B = new int[n];
			for(int i=0;i<n;i++){
				A[i]=in.nextInt();
			}
			for(int i=0;i<n;i++){
				B[i]=in.nextInt();
			}
			Arrays.sort(A);         //升序排列数组,这里java库提供的是一种改进的快速排序算法,也可以自己实现
			Arrays.sort(B);
			for(int i=0;i<n/2;i++){   //因为我们需要降序的序列,逆置
				int t =A[i];
				A[i]=A[n-i-1];
				A[n-i-1]=t;
			}
			for(int i=0;i<n/2;i++){
				int t =B[i];
				B[i]=B[n-i-1];
				B[n-i-1]=t;
			}
//			for(int t:A){
//				System.out.print(t+" ");
//			}
//			for(int t:B){
//				System.out.print(t+" ");
//			}
			int i,k=n-1;
			int j,f=n-1;
			int ji=0;                 //用来记录比较的次数,以跳出循环
			int sum = 0;
			i=j=0;
			while(true){
				if(ji==n) break;
				if(A[i]>B[j]) {i++; j++; ji++; sum+=200; continue;}   
				if(A[i]<B[j]) {k--; j++; ji++; sum-=200; continue;}
				if(A[i]==B[j]){
					if(A[k]>B[f]){k--; f--; ji++; sum+=200;continue;}
					if(A[k]<B[j]){k--; j++; ji++; sum-=200;}
					else{k--; j++; ji++; }
					continue;
				}
			}
			System.out.println(sum);
			n = in.nextInt();
		}
	}
}

总结:这个题目就有一点算法上的深度了,最好现在本上写出基本算法步骤,再根据步骤写代码;如果第一次就直接写代码,肯定会被搞晕的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值