原题链接: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;
}