10026 - Shoemaker's Problem

8 篇文章 0 订阅
/*
贪心

题意:鞋匠接到N份订单,Ti为完成需要的时间,Di为逾期或罚款的金额,要求罚款金额最小的序列。

思路:设从第x位开始,则Tx*(剩余为完成订单)<(剩余订单完成所需时间)*Dx,到局部a、b满足:Ta*Db<Tb*Da则a会排在b之前。所以在cmp中设置函数即可,有一个需要注意就是,如果罚款金额相同需要输出字典序最小的,所以需要在排序中增加稳定性。见①

注意:主要掌握知识点:qsort增加稳定性
*/
#include <cstdio>
#include <cstdlib>
const int nMax=1007;
int T,N;
struct Node
{
	int time;
	int fine;
	int no;//①用来保证排序的稳定性
}node[nMax];
int r[nMax];
int cmp(const void *a,const void *b)
{
	int *pa=(int *)a;
	int *pb=(int *)b;
	int p=node[*pa].time*node[*pb].fine;
	int q=node[*pb].time*node[*pa].fine;
	if(p!=q)
		return p-q;
	else
		return node[*pa].no-node[*pb].no;
}
int main()
{
	//freopen("f://data.in","r",stdin);
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&N);
		for(int i=0;i<N;i++)
		{
			scanf("%d %d",&node[i].time,&node[i].fine);
			r[i]=i;
			node[i].no=i;
		}
		qsort(r,N,sizeof(r[0]),cmp);
		for(int i=0;i<N;i++)
		{
			if(i) printf(" ");
			printf("%d",r[i]+1);
		}
		printf("\n");
		if(T)
			printf("\n");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值