zoukankan      html  css  js  c++  java
  • P1064 金明的预算方案

    P1064 金明的预算方案

    题目描述

    金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过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]。(其中*为乘号)

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

    输入输出格式

    输入格式:

    输入的第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是所属主件的编号)

    输出格式:

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

    输入输出样例

    输入样例#1:
    1000 5
    800 2 0
    400 5 1
    300 5 1
    400 3 0
    500 2 0
    
    输出样例#1:
    2200

    说明

    NOIP 2006 提高组 第二题

    分析:

    这是一个有依赖的背包问题,可以用分组背包的方法来做。

    把所有有依赖的东西全部分在一组里面。然后我们以组为单位进行背包。

    f[i][j]表示前i组物品中消耗为j的最大收益。

    如果我们选第i组物品:

    f[i][j]= f[i-1][j-v[i]]+w[i];

    如果我们不选第i组物品:

    f[i][j]= f[i-1][j];

    然而,在这里,每组物品都包含多种情况:

    只选主件;选主件和附件一;选组件和附件二………….

    依次枚举就好。

    如果情况很多,可以用循环。情况表示方法的话可以考虑用位来表示。

    其实,所有的背包问题都能用分组背包的思想来做:

    比如01背包:每件物品看成一组,每组只有一件物品

    比如完全背包:每件物品看成一组,每组最多W/w[i]件物品

    比如多重背包:每件物品看成一组,每组最多n[i]件物品

    ……..

     1 #include <cstdio>
     2 #include <cstring>
     3 using namespace std;
     4 int f[32010],v[70],q[70],p[70],v1[70],q1[70],v2[70],q2[70];
     5 int mymax(int x,int y)
     6 {
     7     return x>y?x:y;
     8 }
     9 int main()
    10 {
    11     int n,m;
    12     scanf("%d%d",&n,&m);
    13     /*q,v:如是主件则存在这里
    14     q1,v1:如是附件一存在这里
    15     q2,v2:如是附件二则存在这里*/
    16     memset(f,-1,sizeof(f));
    17     memset(q,0,sizeof(q));
    18     memset(q1,0,sizeof(q1));
    19     memset(q2,0,sizeof(q2));
    20     memset(v,0,sizeof(v));
    21     memset(v1,0,sizeof(v1));
    22     memset(v2,0,sizeof(v2));
    23     //请自动忽略以上的的OVO
    24 
    25     f[0]=0;
    26     for (int i=1;i<=m;i++)
    27     {
    28         int a,b,c;
    29         scanf("%d%d%d",&a,&b,&c);
    30         if (c==0)
    31         {
    32             v[i]=a;q[i]=b;  //存为主件  
    33         }    
    34         else 
    35         {
    36             if (q1[c]==0) {q1[c]=b;v1[c]=a;}
    37             else {q2[c]=b;v2[c]=a;}
    38             //存为附件一或附件二
    39         }
    40     }    
    41     for (int i=1;i<=m;i++)
    42     {
    43         for (int j=n;j>=v[i];j--)
    44         {
    45             //if(f[j]!=-1)
    46             {
    47                 if (j-v[i]>=0) f[j]=mymax(f[j],f[j-v[i]]+v[i]*q[i]);//只买一个主件
    48                 if (j-v[i]-v1[i]>=0) f[j]=mymax(f[j],f[j-v[i]-v1[i]]+v[i]*q[i]+v1[i]*q1[i]);//买主件和附件一
    49                 if (j-v[i]-v2[i]>=0) f[j]=mymax(f[j],f[j-v[i]-v2[i]]+v[i]*q[i]+v2[i]*q2[i]);//买主件和附件二
    50                 if (j-v[i]-v1[i]-v2[i]>=0) f[j]=mymax(f[j],f[j-v[i]-v1[i]-v2[i]]+v[i]*q[i]+v1[i]*q1[i]+v2[i]*q2[i]);//买主件和两个附件
    51             }
    52         }
    53     }
    54     int ans=0;
    55     for (int j=1;j<=n;j++)
    56     {
    57         if (f[j]>ans) ans=f[j];
    58         //不一定用最多钱的就是最优的,扫一遍最大值
    59     }
    60     printf("%d
    ",ans);
    61     return 0;
    62 }
  • 相关阅读:
    SAP OPEN UI5 Step 8: Translatable Texts
    SAP OPEN UI5 Step7 JSON Model
    SAP OPEN UI5 Step6 Modules
    SAP OPEN UI5 Step5 Controllers
    SAP OPEN UI5 Step4 Xml View
    SAP OPEN UI5 Step3 Controls
    SAP OPEN UI5 Step2 Bootstrap
    SAP OPEN UI5 Step1 环境安装和hello world
    2021php最新composer的使用攻略
    Php使用gzdeflate和ZLIB_ENCODING_DEFLATE结果gzinflate报data error
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/7425957.html
Copyright © 2011-2022 走看看