经典算法分析与设计——突击战

最近有个朋友问了一个算法分析的题目,感觉有点意思就在这里简单说一下自己的思路吧!

题目:

突击战:

你有 n 个部下, n 个任务,你计划让部下 i 去做任务 i  (1<=i< =n ) ,但部下还不知道任务 的内容,需要你为每个部下解释任务内容(即交代任务)。第 i 个部下需要你花 B(i) 分钟交 代任务,然后他会立刻、独立地、无间断地执行 J( i) 分钟后完成任务。你每次只能给一个 部下交代任务,但部下们可以同时执行各自的任务。 问题:交代任务的顺序不同,完成所有任务所用的时间也不同。你需要考虑的是交代任务的 顺序,在最短的时间内完成所有任务。 输入:每个部下交代任务需要的时间 B(i) 和执行自己任务需要的时间 J(i) ,其中 1<=i< =n 

输入格式:第一行输入部下数 n (它也是任务数) 后面的 n 行,每行两个数字,分别对应 B(i) 和 J (i) 

输出: 1~ n 的一个排列(对应 n 个部下的交代任务次序),以及这种安排下所有任务的完成 时间


算法分析:

根据题目我们可以知道的条件:

  1. 交代任务只能是先交代完本次才能进行下一次交代,也就是说不管怎样排列它们的总时间都是不变的,因此这个不能作为优化的点
  2. 士兵执行任务是可以并列执行的,也就是如果将任务执行的时间安排得紧凑点,让执行任务的等待时间变得最低就可以达到最优,也就是说只要按士兵执行任务时由大到小进行先后排列即可

验证思路:

假设存在两个任务,任务1:交代任务时间为1分钟,执行任务时间为2分钟;任务2:交代任务时间为3分钟,执行任务时间为4分钟

如果直接进行排序:

直接进行排序

按执行任务时间由大到小排序:

按执行任务时间由大到小排序

代码实现(java):

package assault;

import java.util.*;

/**
 * 突击战算法分析:
 * 1、交代任务只能是先交代完本次才能进行下一次交代,也就是说不管怎样排列它们的总时间都是不变的,
 * 因此这个不能作为优化的点
 * 2、士兵执行任务是可以并列执行的,也就是如果将任务执行的时间安排得紧凑点,
 * 让执行任务的等待时间变得最低就可以达到最优,也就是说只要按士兵执行任务时由大到小进行先后排列即可
 * @author jodenhe (824923282@qq.com)
 *
 */
public class Main implements Comparable {  
	int index;//任务标记
	int b;//交代任务时间
	int j; //执行任务时间

	public Main(int index,int b, int j) {
		this.index = index;
		this.b = b;  
		this.j = j;  
	}  
	
	/**
	 * 重新比较方法,实现由大到小排列
	 */
	@Override
	public int compareTo(Object m) {  
		return (j > ((Main) m).j ? -1 : (j == ((Main) m).j) ? 0 : 1);  
	}  

	public static void main(String arg[]) {  
		Scanner cin = new Scanner(System.in);  
		int casenum=0;  
		while (cin.hasNext()) {  
			final int n = cin.nextInt();  
			Main[] m = new Main[n];  
			for (int i = 0; i < n; i++) {  
				m[i]=new Main(i+1,cin.nextInt(),cin.nextInt());  
			}  
			Arrays.sort(m);  
			int time=0,temp=0;  
			System.out.print("1~ n的一个排列:");
			for(int i=0;i<n;i++){  
				System.out.print(m[i].index);
				if (i != n-1) {
					System.out.print(",");
				}else{
					System.out.println();
				}
				time+=m[i].b;  
				if((temp-=m[i].b)<=0)temp=0;  
				if(temp<m[i].j)temp=m[i].j;  
			}  
			time+=temp;  
			System.out.println("Case "+(++casenum)+"(所有任务的完成时间): "+time);
		}  
	}  

} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值