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;
}

提示

动态规划问题

时间限制 1 秒
内存限制 32 MB
讨论 统计
上一题 下一题