1. 程式人生 > >基礎演算法——貪心演算法(聖誕老人的禮物)

基礎演算法——貪心演算法(聖誕老人的禮物)

題目是這樣的:

聖誕節來臨了,中聖誕老人準備分發糖果現在有多箱不同的糖果, 每箱糖果有自己的價值和重量,每箱糖果都可以拆分成任意散裝組合帶走。聖誕老人的馴鹿雪橇最多隻能裝下重量W的糖果,請問聖誕老人最多能帶走多大價值的糖果。

4表示四種糖果,下面跟著四行資料,第一個表示價值,第二個表示重量,15表示聖誕老人的雪橇能裝下的最大重量:1193.0表示能帶走的最大價值

樣例輸入:

 4    15

100    4

412    8

266    7

591    2

樣例輸出

1193.0

思路:當然是拿   價值/重量 比  最大的,通俗一點就是單價最高的嘛!我們可以將每一種糖果封裝成一個結構體,有價值、重量、 價值/重量比 三個屬性。然後按照價值/重量比從大到小排序。先拿第一個結構體陣列,如果不夠再拿第二個......這樣就是一個貪心演算法的思路——從問題的區域性出發,不考慮整體,然後由區域性解構成整體解。排序我們可以採用快排,看程式碼

#include<stdio.h>

typedef struct{
	int value;
	int weight;
	double price;
}Candy;

//交換結構體
void swap(Candy &a,Candy & b)
{
	Candy temp;
	temp=a;
	a=b;
	b=temp;
}
void QuickSort(Candy a[],int left,int right)
{

	int i=left;
	int j=right;
	double key=a[left].price;
	
	if(left>=right)
	{
		return ;
	}
	while(i!=j)
	{
		while(j>i&&a[j].price<=key)
		j--;
		swap(a[i],a[j]);
		while(j>i&&a[i].price>=key)
		i++;
		swap(a[i],a[j]);
	}
	
	QuickSort(a,left,i-1);
	QuickSort(a,i+1,right);
	
} 
int main()
{
    //totalV 是能拿走的總價值
    //keepW  是雪橇還能拿的重量
    
	int i;double totalV=0.0;
	int keepW=0;
	int N,W;
	Candy a[100];
	scanf("%d%d",&N,&W);
	for(i=0;i<N;i++)
	{
		scanf("%d%d",&a[i].value,&a[i].weight);
		a[i].price=(double)a[i].value/(double)a[i].weight;
	}
	 QuickSort(a,0,N-1);
	 
	 i=0;
	 keepW=W;
	 while(keepW>0)
	 {
        //如果能拿的重量大於該糖箱糖果重量,則全拿
	 	if(keepW>=a[i].weight)
	 	{
	 		keepW-=a[i].weight;
	 		totalV+=a[i].weight*a[i].price;
	 		a[i].weight-=a[i].weight;
	 	}
        //否則只能拿 雪橇剩下的重量
	 	else
	 	{
	 		totalV+=keepW*a[i].price;
	 		keepW-=keepW;
	 		a[i].weight-=keepW;
	 		
	 	}
	 	i++;
	 }
	 
	 
	
	 printf("%.1lf\n",totalV);
	
	return 0;
} 

當然除了樣例輸出的結果我們要保證正確之外,還要測試一些特殊資料比如臨界值等等

執行結果

執行結果