zoukankan      html  css  js  c++  java
  • 2017.08.15【NOIP提高组】模拟赛B组 生日聚餐

    ####Description

    Alice在餐馆里当服务员,今天是她生日,她请求厨师帮她准备生日晚餐,晚餐由N种原料做成,每道菜所需每种原料的数量是一样的。
      厨房里有一些原料,但不够,Alice还需要从旁边的超市中购买一些回来。超市里什么原料都有,每种原料都分大包装和小包装。Alice有M元钱,她想利用这M元钱购买原料使得能做出最多的菜。

    ####Input

    第一行包含两个整数N和M(1<=N<=100,1<=M<=100000),接下来N行,每行包含6个正整数,用来描述这种原料的信息,具体如下:
      (1) X:10<=X<=100,表示一道菜中必须含有这种原料的数量;
      (2) Y:1<=Y<=100,表示这种原料厨房已有的数量;
      (3) Sm:1<=Sm<=100,表示超市里小包装中含有这种原料数量;
      (4) Pm:10<=Pm<=100,表示小包装的价格;
      (5) Sv:1<=Sv<=100,表示超市里大包装中含有这种原料数量;   
    (6) Pv:10<=Pv<=100,表示大包装的价格;

    ####Output

    输出最多能做多少道菜。

    ####Sample Input

    输入1:
    2 100
    10 8 10 10 13 11
    12 20 6 10 17 24

    输入2:
    3 65
    10 5 7 10 13 14
    10 5 8 11 14 15
    10 5 9 12 15 16

    ####Sample Output

    输出1:
    5

    输出2:
    2

    ####Data Constraint

    样例1中,Alice购买第一种原料3个小包装和1个大包装,购买第二种原料1个小包装和2个大包装,一共花费3×10+1×11+1×10+2×24=99元。
      两种原料的数量分别为51个(8+3×10+11)和60个(20+1×6+2×17),可以做出5道菜。

    题解:
    可以先求完全背包,然后枚举答案,二分答案也是可以的。  
    这里介绍完全背包。
    我们用f[i,j]表示第i种材料,用j数量的最小价值
    我们就直接用完全背包找出来即可。
    但是我们又发现一个问题:假如你需要用5个,但是只可以用2块钱买3个,那么是需要买6个用4块的,那么久更新一下。
    最后我们枚举答案(也就是从大到小枚举可以做多少道菜),若是你想用二分,也可以。
    但是f数组的空间会炸,所以可以使用动态数组。
    这是个新的东东,大家可以看看。
      下面是一维的定义方式(pascal),二维的只需要加多括号内容

      var
    
        a:array of (array of) longint;
    
      begin
    
        setlength(a,s,(s1))//表示第一维下标开0~s-1大小,括号中,第二维表示下标开从0~s1-1大小
    
      end.
    

    但是根据题意,我们怎么定义呢??
    只需要定义f[n,(m10) div n +100]即可,这是为什么呢?
    我们想:若是根据题意来开到100
    100000当然会炸。上式即可解决。
    我们看看为什么这样搞:
    因为最多是10块钱买100个,也就是1块钱买10个,然后买下来的所有东东平均分成n份,那么每份最多就只可以用(m*10) div n,而且一开始厨房内最多有100个原料,那么就+100即可。

    Code

    uses math;
    var
            i,j,k,l,n,m,ans,small,answer,zd:longint;
            s:ansistring;
            bz:boolean;
            a,b,sm,pm,sv,pv:array[1..100] of longint;
            f:array of array of int64;
    function min(x,y:int64):int64;
    begin
            if x>y then exit(y)
            else exit(x);
    end;
    begin
            readln(n,m);
            i:=n+1;
            j:=(m*10) div n+101;
            setlength(f,i,j);
            for i:=0 to n do
            begin
                    for j:=0 to (m*10) div n+100 do
                    begin
                            f[i,j]:=maxlongint;
                    end;
            end;
            for i:=1 to n do
            begin
                    readln(a[i],b[i],sm[i],pm[i],sv[i],pv[i]);
                    zd:=max(a[i],zd);
                    for j:=1 to b[i] do
                    f[i,j]:=0;
            end;
            j:=1;
            for i:=1 to n do
            begin
                    for j:=sm[i] to (m*10) div n+100 do
                    begin
                            f[i,j]:=min(f[i,j],f[i,j-sm[i]]+pm[i]);
                    end;
                    for j:=sv[i] to (m*10) div n+100 do
                    begin
                            f[i,j]:=min(f[i,j],f[i,j-sv[i]]+pv[i]);
                    end;
            end;
            for i:=1 to n do
            begin
                    for j:=(m*10) div n+100-1 downto 0 do
                    begin
                            f[i,j]:=min(f[i,j],f[i,j+1]);
                    end;
            end;
            for i:=((m*10) div n+100) div zd downto 1 do
            begin
                    if i=46685 then
                    ans:=0;
                    ans:=0;
                    bz:=true;
                    for j:=1 to n do
                    begin
                            if ans+f[j,i*a[j]]<=m then
                            begin
                                    ans:=ans+f[j,i*a[j]];
                            end
                            else
                            begin
                                    bz:=false;
                                    break;
                            end;
                    end;
                    if bz then
                    begin
                            writeln(i);
                            halt;
                    end;
            end;
            writeln(0);
    end.
    
    
    
    我活在这夜里。无论周围多么黑暗,我都要努力发光!我相信着,终有一天,我会在这深邃的夜里,造就一道最美的彩虹。
  • 相关阅读:
    字符串个数的麻烦
    最长单调递增子序列LIS(《算法导论》15.4-5题)
    LCS问题
    关于nextLine()与nextInt()
    调用内部类里,在静态类中调用动态方法的问题
    RTL底层释放或回收对象
    软件需求分、架构设计与建模最佳实践
    Spring@Autowired java.lang.NullPointerException 空指针
    MAC下安装REDIS和REDIS可视化工具RDM并连接REDIS
    Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.apache.catalina.connector.CoyoteWriter and no properties discovered to create BeanSerializer
  • 原文地址:https://www.cnblogs.com/RainbowCrown/p/11148426.html
Copyright © 2011-2022 走看看