1628 - 点菜问题
北大网络实验室经常有活动需要叫外买,但是每次叫外买的报销经费的总额最大为C元,有N种菜可以点,经过长时间的点菜,网络实验室对于每种菜i都有一个量化的评价分数(表示这个菜可口程度),为Vi,每种菜的价格为Pi, 问如何选择各种菜,使得在报销额度范围内能使点到的菜的总评价分数最大。
注意:由于需要营养多样化,每种菜只能点一次。
题目输入
输入的第一行有两个整数C(1 <= C <= 1000)和N(1 <= N <= 100),C代表总共能够报销的额度,N>代表能点菜的数目。接下来的N行每行包括两个在1到100之间(包括1和100)的的整数,分别表示菜的>价格和菜的评价分数。
题目输出
输出只包括一行,这一行只包含一个整数,表示在报销额度范围内,所点的菜得到的最大评价分数。
输入/输出样例
题目输入
1 3 1 5 3 3 2 5 24 8 2 9 8 6 4 1 1 4 2 2 10 5 2 1 1 4
题目输出
5 30
提示
动态规划问题
C语言解答
#include <stdio.h> int max(int a,int b) { return (a>=b?a:b); } int main() { int n,v,i,j,w[101],c[101],f[100001]; while (scanf("%d %d",&v,&n)!=EOF) { for (i=1;i<=n;i++) scanf("%d %d",&c[i],&w[i]); for (i=0;i<=v;i++) f[i]=0; for (i=1;i<=n;i++) for (j=v;j>=c[i];j--) f[j]=max(f[j],f[j-c[i]]+w[i]); printf("%d\n",f[v]); } return 0; }
C++解答
#include <stdio.h> #include <string.h> //#include <windows.h> #define MAXSIZE 1001 #define MAX(a,b) (((a)>(b))?(a):(b)) int value[MAXSIZE],price[MAXSIZE]; //评价和价格 int f[MAXSIZE][MAXSIZE]; int main(int argc, char* argv[]) { // freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int money,count; //总额度money,总共点count个菜 while(scanf("%d %d",&money,&count)!=EOF) { memset(f,0,sizeof(f)); for(int i=1;i <= count;i++) { scanf("%d %d",&price[i],&value[i]); } for(int i=1;i <= count;i++) { for(int j=1;j <= money;j++) { if(price[i] <= j) //当前物品的价格小于j { f[i][j] = MAX(f[i-1][j],f[i-1][j-price[i]]+value[i]); //选择买不买当前物品i } else { f[i][j] = f[i-1][j]; //不买第i个菜 } } } printf("%d\n",f[count][money]); } // system("Pause"); return 0; }
提示
动态规划问题