zoukankan      html  css  js  c++  java
  • [Codevs] 1025 选菜

    1025 选菜

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 黄金 Gold
     
    题目描述 Description

           在小松宿舍楼下的不远处,有PK大学最不错的一个食堂——The Farmer’s Canteen(NM食堂)。由于该食堂的菜都很不错,价格也公道,所以很多人都喜欢来这边吃饭。The Farmer’s Canteen的点菜方式如同在超市自选商品一样,人们从一个指定的路口进去,再从一个指定的路口出来并付款。由于来这里就餐的人数比较多,所以人们自觉地在进入口的时候就排成一个长队,沿着长长的摆放着各式各样佳肴的桌子进行选菜。

           小松发现,这种选菜方式意味着,他不能在选菜的时候离开队伍去拿一些他已经看过了的菜或者没有看过的菜,因为插队是不礼貌的,也是被BS的。

           每个菜有一个价值,而小松也自己给每个菜定了一个在他看来的美味价值,例如红烧小黄鱼在小松看来是美味价值很高的,而花菜在小松眼里则是美味价值极低的菜肴。而有一些菜是营养价值极其高的菜(例如米饭),所以无论它的美味价值是多少,小松都会选择1份。现在小松带了X元钱来食堂就餐,他想知道,在不欠帐的情况下,他选菜的美味价值总合最大是多少。

     
    输入描述 Input Description

           请从输入文件farmer.in中读入相关数据。输入的第一行包括两个个整数n(1≤n100),k(0k实际菜的种类)和一个实数X(0≤X100),表示有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

    分析 Analysis

    一个背包= =

    首先提取出必买的几样菜(妄想拿程序通用性去硬杠而没有预处理提取出来的会WA 3个点= =)

    价格可以x10变成整数(精确到角)

    剩下的就套路了。

    话说用二维数组出了问题= =用线性写法居然对了,蜜汁错误

    代码 Code

     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 
     5 int n,k,w[10000],v[10000],tmp,X,ord[10000],DP[10000],ans;
     6 double cnt;
     7 bool book[10000],ness[10000];
     8 
     9 int main(){
    10     scanf("%d%d%lf",&n,&k,&cnt);
    11     
    12     X = (int)(cnt*10);
    13     
    14     for(int i = 1;i <= n;i++){
    15         scanf("%lf",&cnt);
    16         w[i] = (int)(cnt*10);
    17     }
    18     
    19     for(int i = 1;i <= n;i++)
    20         scanf("%d",&v[i]);
    21     
    22     for(int i = 1;i <= n;i++)
    23         scanf("%d",&ord[i]);
    24         
    25     for(int i = 1;i <= k;i++){
    26         scanf("%d",&tmp);
    27         ness[tmp] = true;
    28     }
    29     
    30     for(int i = 1;i <= n;i++){
    31         if(ness[ord[i]] && !book[ord[i]]){
    32             book[ord[i]] = true;
    33             ans += v[i];
    34             X -= w[i];
    35         }
    36     }
    37     
    38     for(int i = 1;i <= n;i++){
    39         
    40         // A
    41         
    42         if(book[ord[i]]) continue;
    43         for(int j = X;j >= w[i];j--)
    44             DP[j] = max(DP[j],DP[j-w[i]]+v[i]);
    45         book[ord[i]] = true;
    46         
    47         // B
    48         
    49 //        if(book[ord[i]]) for(int j = 0;j <= X;j++) DP[i][j] = DP[i-1][j];
    50 //        else if(ness[ord[i]]) for(int j = w[i];j <= X;j++) DP[i][j] = DP[i-1][j-w[i]]+v[i],book[ord[i]] = true;
    51 //        else{
    52 //            for(int j = w[i];j <= X;j++){
    53 //                if(DP[i-1][j] < DP[i-1][j-w[i]]+v[i]){
    54 //                    book[ord[i]] = true;
    55 //                    DP[i][j] = DP[i-1][j-w[i]]+v[i];
    56 //                }else DP[i][j] = DP[i-1][j];
    57 //            }
    58 //        }book[ord[i]] = true;
    59     }
    60     
    61     printf("%d",ans+DP[X]);
    62 //    printf("%d",DP[n][X]+ans);
    63     
    64     return 0;
    65 }
    = =
    转载请注明出处 -- 如有意见欢迎评论
  • 相关阅读:
    SVN常用命令
    在windows下Oracle10g中创建数据库(一)
    PowerDesigner12.5 常用功能设置
    Windows下oracle xe 10g 手工创建数据库(二)
    Linux环境手动创建oracle10g数据库实践
    SQLSERVER数据库 'XX' 的事务日志已满。若要查明无法重用日志中的空间的原因,请参......
    SP中执行动态组串的sql
    手机号码吉凶测试原理计算公式
    SQL 2005 中 ROW_NUMBER 用法
    IIS 问题汇总
  • 原文地址:https://www.cnblogs.com/Chorolop/p/7445487.html
Copyright © 2011-2022 走看看