Dating with Q (01揹包)

Description


T has being in love with Q since several years ago.Although it is really hard to maintain a long distance relationship(T and Q are not studying in the same university),T endeavors to impress and please Q every time they have a date.And as the winter holiday is approaching,T is racking his brain to make their date interesting and funny.Because Q is crazy about ice cream,T is planning to make a big ice cream which consists of different kind of small ball of ice cream.As T is a romantic and considerate boy,he wants to make Q happy and make sure the big ice cream won't contain too much calories. T finds N kind of small ball of ice cream with calories information of them.Since T knows Q immensely,he knows that if the ith kind small ball of ice cream is added to the big ice cream,Q's happy point will increase pi.


Knowing the ith kind of small ball of ice cream has ci units of calories and pi happy points,T finds it difficult to choose certain kinds of small ball of ice cream to make the big ice cream which has no more than M unit calories and can make Q as happy as possible(having the maximum happy points).Can you help T?


Input


The first line of the input contains two integers M(1<=M<=1000) and N(1<=N<=20).And there will be N lines follow.Each of them involves the information of the ith kind small ball of ice cream,Ci(the calories the ith kind of small ball of ice cream contains) and Pi(the happy point the ith kind of small ball of ice cream contains).


Output


Just output the maximum happy point the big ice cream could have.


Sample Input

100 3
95 120
30 30
10 10


Sample Output

120


題意就是說男主要做冰淇淋給女友,自己有很多類型的冰淇淋球,要用這些冰淇淋球去做一個大冰淇淋。每種冰淇淋球只能用一次且每種冰淇淋球都有一個熱量和半徑。

用戶輸入一個熱量上限一個數量n,還有n個冰淇淋球的數值,你要在保證熱量不超熱量上限的前提下讓半徑之和最大。

可謂是赤裸裸的一道最基本的揹包問題。

我是用一維01揹包的寫法做的,用一維來寫在保證時間複雜度不變的前提下節約了一維的空間,何樂而不爲呢。

#include<stdio.h>
#include<memory.h>
 
const int MAXV=1010;
const int MAXN=25;
 
int dp[MAXV];
int v[MAXN];
int p[MAXN];
 
int main()
{
	int bv,n;
	while(scanf("%d%d",&bv,&n)!=EOF)
	{
		memset(dp,0,(bv+1)*sizeof(int));
		for(int i=1;i<=n;i++)
		scanf("%d%d",&v[i],&p[i]);
		for(int i=1;i<=n;i++)
		for(int j=bv;j>=v[i];j--)
		{
			if(dp[j]<dp[j-v[i]]+p[i])
			dp[j]=dp[j-v[i]]+p[i];
		}
		printf("%d\n",dp[bv]);
	}
	return 0;
}


揹包是一種dp問題,最重要的就是思考如何表示那個狀態轉移。

一維最大值01揹包可以解釋爲:dp[j]=max(dp[j],dp[j-c[i]]+v[i])

i是當前放了前i個物品,j是當前揹包容量,dp[j]是當前容量下的最大價值,c[i]是物品的代價即重量或者體積等,v[i]是物品的價值

這個方程的意思就是當前容量的揹包的價值的最大值要麼是還沒放下第i個物體時的價值,要麼是清掉某些東西直到能放下第i個物品後的最大值

而初始條件是所有dp全部爲0,用這道方程從揹包容量最大放第一個物品開始循環求解即可



發佈了29 篇原創文章 · 獲贊 4 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章