zoukankan      html  css  js  c++  java
  • 分组背包:金明的预算方案

    题目描述 
    Description

    金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”。今天一早,金明就开始做预算了,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:

    主件

    附件

    电脑

    打印机,扫描仪

    书柜

    图书

    书桌

    台灯,文具

    工作椅

    
    

    如果要买归类为附件的物品,必须先买该附件所属的主件。每个主件可以有0个、1个或2个附件。附件不再有从属于自己的附件。金明想买的东西很多,肯定会超过妈妈限定的N元。于是,他把每件物品规定了一个重要度,分为5等:用整数1~5表示,第5等最重要。他还从因特网上查到了每件物品的价格(都是10元的整数倍)。他希望在不超过N元(可以等于N元)的前提下,使每件物品的价格与重要度的乘积的总和最大。

    设第j件物品的价格为v[j],重要度为w[j],共选中了k件物品,编号依次为j1,j2,……,jk,则所求的总和为:

    v[j1]*w[j1]+v[j2]*w[j2]+ …+v[jk]*w[jk]。(其中*为乘号)

    请你帮助金明设计一个满足要求的购物单。

    输入描述 Input Description

    第1行,为两个正整数,用一个空格隔开:

    N m

    (其中N(<32000)表示总钱数,m(<60)为希望购买物品的个数。)

    从第2行到第m+1行,第j行给出了编号为j-1的物品的基本数据,每行有3个非负整数

    v p q

    (其中v表示该物品的价格(v<10000),p表示该物品的重要度(1~5),q表示该物品是主件还是附件。如果q=0,表示该物品为主件,如果q>0,表示该物品为附件,q是所属主件的编号)

    输出描述 Output Description

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

    样例输入 Sample Input

    1000 5

    800 2 0 

    400 5 1

    300 5 1

    400 3 0

    500 2 0

    样例输出 
    Sample Output
    2200

    思路:
    首先,要看清题,p[i]:=p[i]*v[i];
    题中说,附件数<=2,可以看为分组背包
    且每一组中最多有4件物品。
    分组背包的循环方式为
    for i:=1 to 总物体组数 do
    for j:=v downto 0 do
    begin for k:=1 to 物体组中物体数量 do
    if 该物体体积<=j
    then f[j]:=max(f[j],f[j-该物体体积]+该物体价值);
    end;

    code:
    var n,m:longint;
        v,p:array[1..500,0..4]of longint;
        q:array[1..500]of longint;
        son:array[1..500,0..2]of longint;
        i,j,k:longint;
        used:array[1..500]of boolean;
        num,max:longint;
        f:array[0..32000]of longint;
    
    begin 
          readln(n,m);
          fillchar(used,sizeof(used),true);
          for i:=1 to m do
              begin readln(v[i,1],p[i,1],q[i]);
                    v[i,0]:=1;
                    if q[i]>0
                       then begin inc(son[q[i],0]);
                                  son[q[i],son[q[i],0]]:=i;
                                  used[i]:=false;
                            end;
                    p[i,1]:=p[i,1]*v[i,1];
              end;
          num:=m;
          for i:=1 to m do
              if (used[i])and(son[i,0]>0)
                 then begin if son[i,0]=1
                               then begin inc(v[i,0]);
                                          v[i,2]:=v[i,1]+v[son[i,1],1];
                                          p[i,2]:=p[i,1]+p[son[i,1],1];
                                    end;
                            if son[i,0]=2
                               then begin inc(v[i,0]);
                                          v[i,2]:=v[i,1]+v[son[i,1],1];
                                          p[i,2]:=p[i,1]+p[son[i,1],1];
                                          inc(v[i,0]);
                                          v[i,3]:=v[i,1]+v[son[i,2],1];
                                          p[i,3]:=p[i,1]+p[son[i,2],1];
                                          inc(v[i,0]);
                                          v[i,4]:=v[i,1]+v[son[i,1],1]+v[son[i,2],1];
                                          p[i,4]:=p[i,1]+p[son[i,1],1]+p[son[i,2],1];
                                    end;
                      end;
          for i:=1 to m do
              if used[i]
                 then for j:=n downto 0 do
                          begin max:=0;
                                for k:=1 to v[i,0] do
                                    begin if (j>=v[i,k])and(max<f[j-v[i,k]]+p[i,k])
                                             then max:=f[j-v[i,k]]+p[i,k];
                                    end;
                                if f[j]<max
                                   then f[j]:=max;
                          end;
          max:=0;
          for i:=0 to n do
              if f[i]>max
                 then max:=f[i];
          writeln(max);
    
    end.
  • 相关阅读:
    (mysql)卸载5.0安装6.05出现“Error Nr. 2003 : Can't connect to MySQL server on 'localhost' (10061). ”的解决办法
    (Redundancy)关于服务器冗余的几个疑问,请知道的帮忙解答.
    (C#)XML文件操作3
    POJ 3635 Full Tank(最短路径变形 + 优先队列)
    POJ 2286 The Rotation Game(DFS + 迭代加深)
    POJ 1141 Brackets Sequence(区间DP + 打印路径)
    POJ 3460 Booksort(IDA* + 估价函数设计)
    POJ 2908 Quantum(BFS + 优先队列)
    NOI 1997 积木游戏(解题报告)
    NYOJ 110 决斗(区间DP + 黑书例题)
  • 原文地址:https://www.cnblogs.com/spiderKK/p/4908289.html
Copyright © 2011-2022 走看看