1. 程式人生 > >[洛谷]P2095 營養膳食(#貪心 -1.6)

[洛谷]P2095 營養膳食(#貪心 -1.6)

題目描述

Mr.L正在完成自己的增肥計劃。

為了增肥,Mr.L希望吃到更多的脂肪。然而也不能只吃高脂肪食品,那樣的話就會導致缺少其他營養。Mr.L通過研究發現:真正的營養膳食規定某類食品不宜一次性吃超過若干份。比如就一頓飯來說,肉類不宜吃超過1份,魚類不宜吃超過1份,蛋類不宜吃超過1份,蔬菜類不宜吃超過2份。Mr.L想要在營養膳食的情況下吃到更多的脂肪,當然Mr.L的食量也是有限的。

輸入輸出格式

輸入格式:

第一行包含三個正整數n(n≤200),m(m≤100)和k(k≤100)。表示Mr.L每頓飯最多可以吃m份食品,同時有n種食品供Mr.L選擇,而這n種食品分為k類。第二行包含k個不超過10的正整數,表示可以吃1到k類食品的最大份數。接下來n行每行包括2個正整數,分別表示該食品的脂肪指數ai和所屬的類別bi,其中ai≤100,bi≤k。

輸出格式:

包括一個數字即Mr.L可以吃到的最大脂肪指數和。

輸入輸出樣例

輸入樣例#1

6 6 3
3 3 2
15 1
15 2
10 2
15 2
10 2
5 3

輸出樣例#

60

思路

Mr.L能吃的食物總數是有限的,每一類別的食物還分別有限。他希望在這些限制條件下吃到儘可能多的脂肪。

這不就是需要我們貪心選擇一個策略嘛。

如果他優先選擇剩下食物中脂肪最多的,而如果該類別的食物已經吃得超過上限,就丟掉,去吃下一個,不就行了?

所以需要無腦排序

No picture you say a jb.

由圖可知,選擇剩下食物中可選的(即還沒超出限制)、脂肪最多的總是最優的。也許後面的也不錯,但是因為不是最好的才丟掉。

#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
struct food
{
	int a,b;//a是脂肪,b是食物類別
}f[201];
int compare(food first,food next)
{
	return first.a>next.a;
}
int main()
{
	ios::sync_with_stdio(false);
	int i,j,n,m,k,s=0;
	int flag[201]={};
	cin>>n>>m>>k;//m份食品,同時有n種食品供Mr.L選擇,而這n種食品分為k類
	for(i=1;i<=k;i++)
	{
		cin>>flag[i];//每類食物能吃的數量
	}
	for(i=1;i<=n;i++)
	{
		cin>>f[i].a>>f[i].b;
	}
	sort(f+1,f+n+1,compare);//按食物脂肪從大往小排,因為要選脂肪儘量高的
	j=m;i=1;//j為能吃的數量,i為迴圈變數
	while(j>0 && i<=n)//當還能吃的時候並且有足夠多的食物時開始貪心策略
	{	
		if(flag[f[i].b]>0)如果這類食物還能吃
		{
			j--;//食物總類減一次,因為會吃掉一個
			flag[f[i].b]--;//這類食物減一次,因為吃的是這類食物
			s=s+f[i].a;//脂肪累加
		}
		i++;//控制迴圈
	}
	cout<<s<<endl;
	return 0;
}