CODEVS 1025 选菜

来源:互联网 发布:电视直播软件v7.3.4 编辑:程序博客网 时间:2024/06/06 13:19

       好久没写博客了,今天来分享一道01背包。

       这道题大家可以在code vs里面找到,题目的名字叫“选菜”;

              


输入描述 Input Description

       请从输入文件farmer.in中读入相关数据。输入的第一行包括两个个整数n(1≤n≤100),k(0≤k≤实际菜的种类)和一个实数X(0≤X≤100),表示有n个菜式,有k种菜是必选的,小松带来了X元钱(精确到“角”)。接下来的1行包含n个实数,表示菜桌上从入口到出口的所有菜的价格(0价格10,单位“元”,精确到“角”);再接下来的1行包含n个整数,表示菜桌上从入口到出口的所有菜的美味价值(0美味价值100);再接下来一行包含n个整数,表示菜桌上从入口到出口的所有菜的种类编号(1种类编号100)。最后一行包含k个整数分别表示必选菜的种类编号要注意的是,同一种编号的菜可以出现多次,但是他们的价格和美味价值都是一样的。对于同一种菜(无论是不是必选菜),小松最多只会选择1份(买两份红烧豆腐多没意思啊)。另外,必选菜的价格之和一定不超过X

输出描述 Output Description

       请将结果输出到输出文件farmer.out中。输出包含一个整数,表示小松能选到的菜的美味价值总和最大是多少。

       注:你可以假设数据中不会出现小松带的钱不够买必买菜的情况。

 

样例输入 Sample Input

7 1 5.0

4 1 3 0.9 2 0.5 0.9

7 3 5 2 5 0 2

6 3 5 2 4 1 2

2

样例输出 Sample Output

10


题干差不多就这样。

下面我来讲一下我的思路:

首先这题,显而易见是一道01背包,但这题比较棘手的是出现了一个叫“编号”和一个叫“必选菜”的奇奇怪怪的东西。

所以必须先把必选菜处理掉,就可以DP了。

下面是我的AC代码

#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int INF=1223;
int i,j;
int sum=0;
int maxn[105][1005];
int m1[105]={0};
int m2[105]={0};
double M1[105]={0};
int v1[105]={0};
int v2[105]={0};
int a1[105]={0};
int bee[105]={0};
int n,k,x;
double X;
int main()
{
 for(i=0;i<105;i++)
 {
  for(j=0;j<1005;j++)
  {
   maxn[i][j]=0;
  }
 }
 scanf("%d%d%lf",&n,&k,&X);
 X*=10;
 x=X;
 for(i=1;i<=n;i++)
 {
  scanf("%lf",&M1[i]);
  M1[i]*=10;
  m1[i]=M1[i];
 }
 for(i=1;i<=n;i++)
 {
  scanf("%d",&v1[i]);
 }
 for(i=1;i<=n;i++)
 {
  scanf("%d",&a1[i]);
 }
 for(i=1;i<=k;i++)
 {
  scanf("%d",&bee[i]);
 }
//in
 for(i=1;i<=n;i++)
 {
  m2[a1[i]]=m1[i];
  v2[a1[i]]=v1[i];
 }
 for(i=1;i<=k;i++)
 {
  if(m2[bee[i]]!=INF)
  {
   x-=m2[bee[i]];
   sum+=v2[bee[i]];
   m2[bee[i]]=INF;
  }
 }
//qi qi guai guai de dong xi
 for(i=1;i<=n;i++)
 {
  for(j=1;j<=x;j++)
  {
   if(j-m2[i]>=0&&maxn[i-1][j]<maxn[i-1][j-m2[i]]+v2[i]) maxn[i][j]=maxn[i-1][j-m2[i]]+v2[i];
   else maxn[i][j]=maxn[i][j]=maxn[i-1][j];
  }
 }
//DP
printf("%d",maxn[n][x]+sum);
}


0 0