洛谷 P1223 排队接水 题解

题目详细:P1223 排队接水

贪心算法解决
寻求最优解,让平均等待时间最短

排序为什么要从小排到大呢?

因为!!

首先做个数学假设,
一个队列任意两个相邻的元素a,b
设a的打水时间Ti1< b的打水时间Ti2

  1. 如果a排在b前面,则排队总时间为T1=Ti1
  2. 如果b排在a前面,则排队总时间为T2=Ti2
    T1 < T2 则a排在b前面 排队时间最短,也就是说明,打水时间越短的排在越前面则排队时间越短。
#include
#include 
using namespace std;

const int N = 1000;
int a[N];//原数组 
int item[N];//记录从小到大的下标 
//int t = 0;//此前访问过_个 
long s[N];//记录排序后当前这位兄弟要等待的时间 
int flag[N];//访问记录 (0:未访问 1:访问)

int main()
{
	int n;
	cin >> n;
	for(int i = 0; i < n; i++){
		cin >> a[i];
		flag[i] = 0;
	}
	for(int i = 0; i < n; i++){
		int temp;//临时工,作为此前最小的下标 
		
		int x = 0;//寻找未访问过的下标 
		while(1)
		{
			if(flag[x])
				x++;
			else{
				temp = x;
				break;	
			} 
		}
		
		for(int j = 0; j < n; j++)//临时工开始工作 
		{
			if(!flag[j])
			{
				if(a[j] < a[temp])
				{
					temp = j;
				}
			}
		}
		
		item[i] = temp;//将临时工的下标记录到item[]重 
		flag[temp] = 1;//临时工位置访问(a[]中位置)
		//s[i]=a[item[i]]; 
		 
		if(i==0){
			//s[i]=a[temp];
			s[i]=0;
		} 
		else{
			//s[i] = s[i-1]+a[temp];
			s[i] = s[i-1] + a[item[i-1]];
		}
		//cout << "s["<
	}
	double sum = 0;
	for(int i = 0; i < n; i++){
		cout << item[i]+1 << " ";	
		sum += s[i];	
	}
		
	cout << endl;
	cout << fixed << setprecision(2) << sum/(double)n;
	return 0;
}

耶!!!
写作业去咯。

你可能感兴趣的:(练习)