HDU's ACM 1009 FatMouse' Trade

原题链接:HDU's ACM 1009 FatMouse' Trade


分析:用贪心算法解决。读入数组之后,按照J/F大小降序排列,正确性如下:a.若A'是问题P(A,W)的一个最优解,则a0总可以包含在A'中:i)若a0已在A'中,则得证;ii)若a0不在A'中,则取其中任意一个ak替换为a0后,A''不小于A';b.设A'是P(A,W)的一个最优解,且a0属于A',则A'\{a0}也是P({A\{a0},W)的一个最优解:假设命题不成立,则存在A"\{a0}是最优解,则A"才是P(A,W)的最优解,与假设矛盾。综上,反复运用结论a,b,可知{a0...ak}为P(A,W)的最优解


AC Code:

#include <stdio.h>
#include <string.h>
#define MAXN 1000 + 10
typedef struct Node{
	int J;
	int F;
	double weight;
} Node;

Node arr[MAXN];

int Partition(Node arr[], int left, int right)
{
	int i, j;
	Node tmp;
	if(left < right){
		i = left;
		j = right;
		tmp.J = arr[i].J;
		tmp.F = arr[i].F;
		tmp.weight = arr[i].weight;
		while(i<j) {
			while(i<j && tmp.weight>arr[j].weight)
				j--;
			if(i<j) {
				arr[i].J = arr[j].J;
				arr[i].F = arr[j].F;
				arr[i].weight = arr[j].weight;
				i++;
			}

			while(i<j && tmp.weight<=arr[i].weight)
				++i;
			if(i<j){
				arr[j].J = arr[i].J;
				arr[j].F = arr[i].F;
				arr[j].weight = arr[i].weight;
				j--;
			}
			arr[i].J = tmp.J;
			arr[i].F = tmp.F;
			arr[i].weight = tmp.weight;
		}
		return i;
	}
	return -1;
}

void QuickSort(Node arr[], int left, int right)
{
	int pos;
	if(left < right){
		pos = Partition(arr, left, right);
		QuickSort(arr, left, pos-1);
		QuickSort(arr, pos+1, right);
	}
}

int main()
{
	int M, N;
	int i;
	double res;

#ifdef DEBUG
	freopen("1009.in", "r", stdin);
#endif

	while(scanf("%d%d", &M, &N) == 2){

		memset(arr, 0, MAXN*sizeof(Node));

		if(M == -1 && N == -1)
			break;

		for(i=1;i<=N;++i){
			scanf("%d%d", &arr[i].J, &arr[i].F);
			arr[i].weight = 1.0*arr[i].J/arr[i].F;
		}
		QuickSort(arr, 1, N);

		res = 0;
		i = 1;
		while(M && N-i+1){
			if(M>=arr[i].F){
				res += arr[i].J;
				M -= arr[i].F;
			} else {
				res += arr[i].J * 1.0 * M / arr[i].F;
				M = 0;
			}
			++i;
		}
		printf("%.3lf\n", res);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值