Dating with Q (01背包)

来源:互联网 发布:收银软件库存一体 编辑:程序博客网 时间:2024/06/02 05:48

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 395 12030 3010 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,用这道方程从背包容量最大放第一个物品开始循环求解即可



0 0
原创粉丝点击