• 动归皆背包——那些做过的背包


    这里主要是一些简单的背包问题,单独开篇似乎没有必要,就把题目都堆在这里了

    题目描述

    金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”。今天一早金明就开始做预算,但是他想买的东西太多了,肯定会超过妈妈限定的N元。于是,他把每件物品规定了一个重要度,分为5等:用整数1~5表示,第5等最重要。他还从因特网上查到了每件物品的价格(都是整数元)。他希望在不超过N元(可以等于N元)的前提下,使每件物品的价格与重要度的乘积的总和最大。
    设第j件物品的价格为v[j],重要度为w[j],共选中了k件物品,编号依次为j1,j2,……,jk,则所求的总和为:
    v[j1]*w[j1]+v[j2]*w[j2]+ …+v[jk]*w[jk]。(其中*为乘号)
    请你帮助金明设计一个满足要求的购物单。

    输入输出格式

    输入格式:

    输入的第1行,为两个正整数,用一个空格隔开:
    N m
    (其中N(<30000)表示总钱数,m(<25)为希望购买物品的个数。)
    从第2行到第m+1行,第j行给出了编号为j-1的物品的基本数据,每行有2个非负整数
    v p
    (其中v表示该物品的价格(v<=10000),p表示该物品的重要度(1~5))

    输出格式:

    输出只有一个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的最大值(<100000000)。

    输入输出样例

    输入样例#1:

    1000 5
    800 2
    400 5
    300 5
    400 3
    200 2
    

    输出样例#1:

    3900

    说明

    NOIP 2006 普及组 第二题

    【解题思路】

    标准01背包,没啥好说的

     1 program HappyJinMing;  
     2 function max(x,y:Longint):longint;  
     3 begin  
     4     if x>y then exit(x) else exit(y);  
     5 end;  
     6 var  
     7 f:array[0..25,0..30000] of int64;  
     8 a,b:array[0..25] of longint;  
     9 i,j,m,n:Longint;  
    10 begin  
    11     read(n,m);  
    12     for i:=1 to m do read(a[i],b[i]);  
    13     for i:=1 to m do  
    14         for j:=n downto 1 do  
    15         begin  
    16             if a[i]<=j then f[i,j]:=max(f[i-1,j],f[i-1,j-a[i]]+a[i]*b[i])  
    17             else f[i,j]:=f[i-1,j];  
    18         end;  
    19         writeln(f[m,n]);  
    20 end.  
    View Code

    题目背景

    uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家……餐馆,很低端的那种。 uim指着墙上的价目表(太低级了没有菜单),说:“随便点”。

    题目描述

    不过uim由于买了一些辅(e)辅(ro)书,口袋里只剩M元(M<=10000)。
    餐馆虽低端,但是菜品种类不少,有N种(N<=100),第i种卖ai元(ai<=1000)。由于是很低端的餐馆,所以每种菜只有一份。
    小A奉行“不把钱吃光不罢休”,所以他点单一定刚好吧uim身上所有钱花完。他想知道有多少种点菜方法。
    由于小A肚子太饿,所以最多只能等待1秒。

    输入输出格式

    输入格式:

    第一行是两个数字,表示N和M。
    第二行起N个正数ai(可以有相同的数字,每个数字均在1000以内)。

    输出格式:

    一个正整数,表示点菜方案数。

    输入输出样例

    输入样例#1:

    4 4
    1 1 2 2
    

    输出样例#1:

    3
    【解题思路】
    这是属于那种需要统计方案的背包
    f[i,j]表示选到第i种时剩余钱数为j可方案数
    f[i,j]=f[i-1,j]+f[i-1,j-a[i]];
    初始条件是  f[i,0]:=1;  
     1 program SmallAChoice;  
     2 var f:array[0..100,0..10000] of longint;  
     3     a:Array[0..100] of longint;  
     4     m,n,i,j:longint;  
     5 begin  
     6     read(n,m);  
     7     for i:=1 to n do read(a[i]);  
     8     for i:=0 to n do  
     9     begin  
    10         f[i,0]:=1;  
    11     end;  
    12     for i:=1 to n do  
    13         for j:=m downto 1 do  
    14         begin  
    15           if j>=a[i] then  
    16   
    17             f[i,j]:=f[i-1,j-a[i]]+f[i-1,j]  
    18            else f[i,j]:=f[i-1,j];  
    19         end;  
    20     write(f[n,m])  
    21 end.  
    View Code

    题目描述

    辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。” 

    如果你是辰辰,你能完成这个任务吗?

    输入输出格式

    输入格式:

    输入文件medic.in的第一行有两个整数T(1 <= T <= 1000)和M(1 <= M <= 100),用一个空格隔开,T代表总共能够用来采药的时间,M代表山洞里的草药的数目。接下来的M行每行包括两个在1到100之间(包括1和100)的整数,分别表示采摘某株草药的时间和这株草药的价值。

    输出格式:

    输出文件medic.out包括一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。

    输入输出样例

    输入样例#1:

    70 3
    71 100
    69 1
    1 2
    
    

    输出样例#1:

    3

    说明

    对于30%的数据,M <= 10;
    对于全部的数据,M <= 100。
    NOIP2005普及组第三题

    【解题思路】

    这个题好像和第一题并没有什么区别

    代码是记忆化写的

     1 program gold1;  
     2 var g,p:array [0..99] of longint;//g,gold缩写 ,表示金矿数 ,p,people缩写,表示人数  
     3     i,gold,ren,sum:longint;//ren,gold你懂得  
     4     f:array[0..1000,0..99] of longint;//用于记忆的数组  
     5 function max(a,b:longint):longint;//求较大值的函数  
     6 begin  
     7    if a>b then exit(a) else exit(b);  
     8 end;  
     9 function find(n,m:longint):longint;  
    10 var t:longint;  
    11 begin  
    12    if m=0 then//边界条件……当等于0的时候  
    13    begin  
    14       if n>=p[0] then  
    15       begin  
    16          f[n,0]:=g[0];  
    17          find:=g[0];  
    18       end  
    19       else  
    20       begin  
    21          f[n,0]:=0;  
    22          find:=0;  
    23       end;  
    24    end;  
    25    if f[n,m]<>-1 then exit(f[n,m]);//记忆搜索的过程  
    26    if f[n,m]=-1 then//对未储存的数据进行搜索  
    27    begin  
    28       if n>=p[m] then//如果比他大再去求较大值  
    29       begin  
    30       t:=max(find(n-p[m],m-1)+g[m],find(n,m-1));//避免重复计算,学会使用中间变量  
    31       f[n,m]:=t;  
    32       find:=t;  
    33       end  
    34       else//否则直接返回f(n,m-135       begin  
    36       t:=find(n,m-1);  
    37       f[n,m]:=t;  
    38       exit(t);  
    39       end;  
    40    end;  
    41 end;  
    42 begin  
    43    read(ren,gold);  
    44    for i:=0 to gold-1 do  
    45    begin  
    46        read(p[i],g[i]);  
    47    end;  
    48    fillchar(f,sizeof(f),char(-1));//数组填无效值  
    49   
    50    sum:=find(ren,gold-1);  
    51    writeln(sum);  
    52   
    53 end.  
    View Code

    题目描述

    有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30,每个物品有一个体积(正整数)。

    要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

    输入输出格式

    输入格式:

    一个整数,表示箱子容量
    一个整数,表示有n个物品
    接下来n行,分别表示这n 个物品的各自体积

    输出格式:

    一个整数,表示箱子剩余空间。

    输入输出样例

    输入样例#1:

    24
    6
    8
    3
    12
    7
    9
    7
    

    输出样例#1:

    0
    

    说明

    NOIp2001普及组 第4题

    【解题思路】

    这个题和上一个题也没有什么本质上的区别。。。全是01背包算是堆砌水题吗?

     1 ar g,p:array [0..30] of longint;  
     2     i,gold,ren,sum:longint;  
     3     f:array[0..20000,0..30] of longint;  
     4 function min(a,b:longint):longint;  
     5 begin  
     6    if a>b then exit(b) else exit(a);  
     7 end;  
     8 function find(n,m:longint):longint;  
     9 var t:longint;  
    10 begin  
    11    if m=0 then  
    12    begin  
    13       if n>=g[0] then  
    14       begin  
    15          f[n,0]:=n-g[0];  
    16          n:=n-g[0];  
    17   
    18          exit(n);  
    19       end  
    20       else  
    21       begin  
    22          f[n,0]:=n;  
    23          find:=n;  
    24       end;  
    25    end;  
    26    if f[n,m]<>-1 then exit(f[n,m]);  
    27    if f[n,m]=-1 then  
    28    begin  
    29       if n>g[m] then  
    30       begin  
    31       t:=min(find(n-g[m],m-1),find(n,m-1));  
    32       f[n,m]:=t;  
    33       find:=t;  
    34       end  
    35       else  
    36       begin  
    37       t:=find(n,m-1);  
    38       f[n,m]:=t;  
    39       exit(t);  
    40       end;  
    41    end;  
    42 end;  
    43 begin  
    44    read(ren,gold);  
    45    for i:=0 to gold-1 do  
    46    begin  
    47        read(g[i]);  
    48    end;  
    49    fillchar(f,sizeof(f),char(-1));  
    50   
    51    sum:=find(ren,gold-1);  
    52    writeln(sum);  
    53   
    54 end.  
    View Code

    题目背景

    此题为NOIP2005普及组第三题的疯狂版。 此题为纪念LiYuxiang而生。

    题目描述

    LiYuxiang是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同种类的草药,采每一种都需要一些时间,每一种也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。” 
    如果你是LiYuxiang,你能完成这个任务吗?
    此题和原题的不同点:
    1.每种采药可以无限制地疯狂采摘。
    2.药的种类眼花缭乱,采药时间好长好长啊!师傅等得菊花都谢了!

    输入输出格式

    输入格式:

    输入第一行有两个整数T(1 <= T <= 100000)和M(1 <= M <= 10000),用一个空格隔开,T代表总共能够用来采药的时间,M代表山洞里的草药的数目。接下来的M行每行包括两个在1到10000之间(包括1和10000)的整数,分别表示采摘某种草药的时间和这种草药的价值。

    输出格式:

    输出一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。

    输入输出样例

    输入样例#1:

    70 3
    71 100
    69 1
    1 2
    

    输出样例#1:

    140
    

    说明

    对于30%的数据,M <= 1000;
    对于全部的数据,M <= 10000。
    加油LiYuxiang,第一个AC留给你!

    【解题思路】

    终于。。。终于不是01背包了,这是一个完全背包,把循环顺序改改就好了。

     1 var z,x,i,j,n,m,w,h:longint;  
     2   a,b:array[1..100000]of longint;  
     3   f:array[0..100000]of int64;  
     4 begin  
     5   readln(z,x);  
     6   for i:=1 to x do  
     7     readln(a[i],b[i]);  
     8   
     9   for i:=1 to x do  
    10   for j:=a[i] to z do  
    11     if f[j]<f[j-a[i]]+b[i] then f[j]:=f[j-a[i]]+b[i];  
    12   
    13   write(f[z]);  
    14 end.  
    View Code
    题目描述 Description

    背包体积为V ,给出N个物品,每个物品占用体积为Vi,价值为Wi,每个物品要么至多取1件,要么至多取mi件(mi > 1) , 要么数量无限 , 在所装物品总体积不超过V的前提下所装物品的价值的和的最大值是多少?

    输入描述 Input Description

    第一行两个数N,V,下面N行每行三个数Vi,Wi,Mi表示每个物品的体积,价值与数量,Mi=1表示至多取一件,Mi>1表示至多取Mi件,Mi=-1表示数量无限

    输出描述 Output Description

    1个数Ans表示所装物品价值的最大值

    样例输入 Sample Input

    2 10

    3 7 2

    2 4 -1

    样例输出 Sample Output

    22

    数据范围及提示 Data Size & Hint

    对于100%的数据,V <= 200000 , N <= 200

    【解题思路】

    终于来了一个高难度背包,因为它的数据范围灰常灰常大,我的代码完完全全超时,但是思路是在这的,神马多重背包的二进制拆分之类的都有,虽然他不过

     1 program mix;
     2 var f:array[0..200000] of longint;
     3     v,w,m,s:array[0..200000] of longint;
     4     i,j,k,n,v1,p,sum:Longint;
     5 begin
     6     s[0]:=1;
     7     for i:=1 to 30 do s[i]:=s[i-1]*2;
     8     read(n,v1);
     9     sum:=n;
    10     for i:=1 to n do
    11     begin
    12         read(v[i],w[i],m[i]);
    13         if m[i]>1 then
    14         begin
    15             p:=1;
    16             while m[i]>=s[p] do
    17             begin
    18                 inc(sum);
    19                 v[sum]:=s[p]*v[i];
    20                 w[sum]:=s[p]*w[i];
    21                 m[sum]:=1;
    22                 dec(m[i],s[p]);
    23             end;
    24             if (m[i]>=2) then
    25             begin
    26                 inc(sum);
    27                 v[sum]:=m[i]*v[i];
    28                 w[sum]:=m[i]*w[i];
    29                 m[sum]:=1;
    30                 m[i]:=0;
    31             end;
    32         end;
    33     end;
    34     for i:=1 to sum do
    35     begin
    36         if m[i]=-1 then
    37         for j:=v[i] to v1 do
    38         begin
    39         if f[j]<f[j-v[i]]+w[i] then f[j]:=f[j-v[i]]+w[i];
    40         end
    41         else
    42         begin
    43             for k:=1 to m[i] do
    44                 for j:=v1 downto k*v[i] do
    45                 begin
    46                     if f[j]<f[j-v[i]*k]+w[i]*k then
    47                     f[j]:=f[j-v[i]*k]+w[i]*k;
    48                 end;
    49         end;
    50     end;
    51     writeln(f[v1]);
    52 end.
    View Code

  • 相关阅读:
    【一周读书】哲学家,你们都干了些什么?
    我的软件工程课目标
    【一周读书】《把时间当作朋友》《一个人就是一支骑兵》读书心得
    LANMP安全配置学习之PHP安全配置
    XXE漏洞学习
    利用bWAPP学习SSRF
    Vulnhub靶场之DC-1
    74CMS4.1.2.4版本黑盒测试
    业务逻辑漏洞——浅谈验证码漏洞
    bWAPP靶场之HTML Injection(GET)
  • 原文地址:https://www.cnblogs.com/wuminyan/p/4746760.html
Copyright © 2020-2023  润新知