1. 程式人生 > >1020 月餅(C語言版 + 註釋 + 貪心演算法)

1020 月餅(C語言版 + 註釋 + 貪心演算法)

月餅是中國人在中秋佳節時吃的一種傳統食品,不同地區有許多不同風味的月餅。現給定所有種類月餅的庫存量、總售價、以及市場的最大需求量,請你計算可以獲得的最大收益是多少。

注意:銷售時允許取出一部分庫存。樣例給出的情形是這樣的:假如我們有 3 種月餅,其庫存量分別為 18、15、10 萬噸,總售價分別為 75、72、45 億元。如果市場的最大需求量只有 20 萬噸,那麼我們最大收益策略應該是賣出全部 15 萬噸第 2 種月餅、以及 5 萬噸第 3 種月餅,獲得 72 + 45/2 = 94.5(億元)。

輸入格式:

每個輸入包含一個測試用例。每個測試用例先給出一個不超過 1000 的正整數 N 表示月餅的種類數、以及不超過 500(以萬噸為單位)的正整數 D 表示市場最大需求量。隨後一行給出 N 個正數表示每種月餅的庫存量(以萬噸為單位);最後一行給出 N 個正數表示每種月餅的總售價(以億元為單位)。數字間以空格分隔。

輸出格式:

對每組測試用例,在一行中輸出最大收益,以億元為單位並精確到小數點後 2 位。

輸入樣例:

3 20
18 15 10
75 72 45

輸出樣例:

94.50

關鍵之處:

  • 將月餅按照單價降序進行排列。我使用了C自帶的快速排序和自己寫的選擇排序函式。

程式碼(快速排序):

#include <stdio.h>
#include <stdlib.h>
#define MAXN 1001
/*定義月餅結構體為mooncake*/
typedef struct {
	float stock;    //庫存。
	float price;    //每款月餅總價。
	float each;    //每款月餅單價。
} mooncake;
int cmp ( const void *a, const void*b ) {
	mooncake c1 = *(mooncake *)a;    //將指標a強制轉化為mooncake結構體型別。
	mooncake c2 = *(mooncake *)b;
	return c2.each > c1.each;    //按單價each降序返回。
}
int main(void) {
	int N, i;
	float D, total;
	mooncake cake[MAXN];
	
	scanf("%d %f", &N, &D);
	for ( i = 0; i < N; i++ )	scanf("%f", &cake[i].stock);	
	for ( i = 0; i < N; i++ )	scanf("%f", &cake[i].price);
	for ( i = 0; i < N; i++ )	cake[i].each = cake[i].price / cake[i].stock;
    /*陣列名,陣列大小,每個陣列元素大小,比較函式*/
	qsort ( cake, N, sizeof(mooncake), cmp );    //sizeof(cake[0])也行。
	total = 0;
    /*月餅已經按單價降序排號,只需遍歷*/
	for( i = 0; i < N && D > 0; i++ ) {
		if ( cake[i].stock <= D ) {    //某款月餅庫存比需求量低。
			total += cake[i].price;    //這款月餅總價全部放入銷售額。
			D -= cake[i].stock;    //需求量扣除這款月餅的庫存。
		} else {    //某款月餅的庫存滿足了需求量。
			total += D * cake[i].each;    //銷售額 = 需求量 * 這款月餅單價。
			D = 0;    //需求置零,退出迴圈。
		}
	}
	printf("%.2f\n", total);
	
	return 0;
}

程式碼(選擇排序):

#include <stdio.h>
#define MAXN 1001
typedef struct {
	float stock;
	float price;
	float each;
} mooncake;
/*氣泡排序*/
void sort ( mooncake cake[], int N ) {
	int i, j;
	mooncake temp;    //這裡注意臨時變數得是一個結構體型別。
	for ( i = 0; i < N-1; i++ ) 
		for ( j = i+1; j < N; j++ ) 
			if ( cake[i].each < cake[j].each ) {
				temp = cake[i];
				cake[i] = cake[j];
				cake[j] = temp;
			}
}
int main(void) {
	int N, i;
	float D, total;
	mooncake cake[MAXN];
	
	scanf("%d %f", &N, &D);
	for ( i = 0; i < N; i++ )	scanf("%f", &cake[i].stock);	
	for ( i = 0; i < N; i++ )	scanf("%f", &cake[i].price);
	for ( i = 0; i < N; i++ )	cake[i].each = cake[i].price / cake[i].stock;
	sort ( cake, N );
	total = 0;
	for( i = 0; i < N && D > 0; i++ ) {
		if ( cake[i].stock <= D ) {
			total += cake[i].price;
			D -= cake[i].stock;
		} else {
			total += D * cake[i].each;
			D = 0;
		}
	}
	printf("%.2f\n", total);
	
	return 0;
}