UVa 10026 - Shoemaker's Problem

传送门UVa 10026 - Shoemaker's Problem


题意:鞋匠有N双鞋等着修,但是他每天只能修一双鞋。没有被轮到的鞋就要罚款。。。。求鞋匠的最小罚款。

(这怎么看都是赔本生意吧)(╯‵□′)╯  ┴─┴ 


根据fine / day从大到小排序。证明请参考Staginner:

引用一下

对于为什么贪心策略是这个样子的,我们不妨拿相邻的两个事件a、b来说明一下。由于a、b之后的事件是固定的,所以我们无论排成ab还是排成ba后面部分的损失都是固定的,那么损失的差别主要来源于究竟是排成ab还是排b成a。排ab的损失为ta*fb,排ba的损失为tb*fa,那么如果ta*fb<tb*fa,我们就排成ab,这样可以得到fa/ta>fb/tb,推而广之,就得到了我们的贪心策略。


#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

struct PEO
{
	double day, fine;
	int num;
};

bool cmp(const PEO &a, const PEO &b)
{
	
	if (a.fine / a.day != b.fine / b.day)
		return a.fine / a.day > b.fine / b.day;
	else
		return a.num < b.num;
}

int main()
{
	//freopen("input.txt", "r", stdin);
	vector<PEO> ve;
	PEO temp;
	int T, i, j, n;
	scanf("%d", &T);
	while (T--)
	{
		ve.clear();
		scanf("%d", &n);
		for (i = 0; i < n; i++)
		{
			scanf("%lf%lf", &temp.day, &temp.fine);
			temp.num = i + 1;
			ve.push_back(temp);
		}
		sort(ve.begin(), ve.end(), cmp);
		for (i = 0; i < ve.size() - 1; i++)
			printf("%d ", ve[i].num);
		printf("%d\n", ve[i].num);
		if (T)
			printf("\n");
	}
	return 0;
}




你可能感兴趣的:(ACM,uva)