1. 程式人生 > >貪心演算法的應用(PAT 1070 Mooncake)

貪心演算法的應用(PAT 1070 Mooncake)

貪心法是求解一類最優化問題的方法,它總是考慮區域性情況下的最優解

比如在huffman樹的構造中,利用貪心演算法依次選取陣列中權值最大的兩個結點組合成新的結點,依次類推

該演算法確定全域性結果是最優的(每一次決策都是最優的決策)

比如下面這麼一道題:

Mooncake is a Chinese bakery product traditionally eaten during the Mid-Autumn Festival. Many types of fillings and crusts can be found in traditional mooncakes according to the region's culture. Now given the inventory amounts and the prices of all kinds of the mooncakes, together with the maximum total demand of the market, you are supposed to tell the maximum profit that can be made.

Note: partial inventory storage can be taken. The sample shows the following situation: given three kinds of mooncakes with inventory amounts being 180, 150, and 100 thousand tons, and the prices being 7.5, 7.2, and 4.5 billion yuans. If the market demand can be at most 200 thousand tons, the best we can do is to sell 150 thousand tons of the second kind of mooncake, and 50 thousand tons of the third kind. Hence the total profit is 7.2 + 4.5/2 = 9.45 (billion yuans).

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive integers N (≤1000), the number of different kinds of mooncakes, and D (≤500 thousand tons), the maximum total demand of the market. Then the second line gives the positive inventory amounts (in thousand tons), and the third line gives the positive prices (in billion yuans) of N kinds of mooncakes. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the maximum profit (in billion yuans) in one line, accurate up to 2 decimal places.

Sample Input:

3 200
180 150 100
7.5 7.2 4.5

Sample Output:

9.45

現在月餅需求量為D,已知n種月餅的庫存和總售價,問如何銷售這些月餅,使收益能夠最大

首先確定貪心策略:“總是選擇單價最高的月餅銷售,可以獲得最大收益"

然後進行決策:

(1)如果當前單價最高的月餅庫存量滿足需求量,直接全部購買該種月餅即可

(2)  如果庫存量無法滿足需求量,將該月餅的庫存全部買下,需求量減去該月餅庫存量,然後進行下一步決策(即下一單價最高月餅能否滿足)

編寫程式碼如下:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;

struct moonCake
{
	double price;   //單價
	double store;   //總庫存量
	double sell;    //總售價
}moonCakes[1010];

bool cmp(moonCake a, moonCake b) {  //將月餅根據單價排序
	return a.price > b.price;
}

int main() {
	int N;
	double M;  //N月餅種類,M需求量
	double amount = 0.0;  //總收益
	scanf("%d %lf", &N, &M);
	for (int i = 0; i < N; ++i) {
		scanf("%lf", &moonCakes[i].store);
	}
	for (int i = 0; i < N; ++i) {
		scanf("%lf", &moonCakes[i].sell);
		moonCakes[i].price = moonCakes[i].sell / moonCakes[i].store;
	}
	sort(moonCakes, moonCakes + N, cmp);  //將價格從高到低依次排序
	for (int i = 0; i < N; ++i) {
		if (moonCakes[i].store > M) {   //如果庫存大於需求的話
			amount += moonCakes[i].price*M;
			break;
		}
		else {
			amount += moonCakes[i].sell;   //否則直接全拿下
			M -= moonCakes[i].store;
		}
	}
	
	printf("%.2f\n", amount);

	system("PAUSE");
	return 0;
}