zoukankan      html  css  js  c++  java
  • 51Nod 1086 背包问题 (逐步加强版) 【背包/dp】

    51Nod 1085~1087  背包问题

    第一种:

    最基本的  n*w ,f[i][j] (j>=w[i]) = max(f[i-1][j] , f[i-1][j-w[i]+p[i] );   数组还可以用滚动压成一维。

    代码不贴,度娘慷慨!

    第二种:

    多重背包。加了一维物品数。直接做多枚举一维物品数,数据大要T掉。所以我们采用一种优化叫二进制分解。

    就是把一个物品的个数拆成二进制,然后把每组 2^i 个物品组合在一起看成单独的一个物品,这样我们就实现了把多重背包转换成 01背包了。 剩下的直接按上面的做就可以了。。

    代码:

     1 #include<bits/stdc++.h>
     2 #define LL long long
     3 using namespace std;
     4 const int W=5*1e4;
     5 int n,w,f[W+10],two[10];
     6 int main()
     7 {
     8     scanf("%d%d",&n,&w);
     9     two[0]=1;
    10     for (int i=1; i<=7; i++) two[i]=two[i-1]*2;
    11     for (int k=1; k<=n; k++)
    12     {
    13         int ww,p,c,ii=0; scanf("%d%d%d",&ww,&p,&c);
    14         for (int i=0; i<=7; i++)
    15           if (c>=two[i])
    16             {
    17                 for (int j=w-ww*two[i]; j>=0; j--)
    18                   f[j+ww*two[i]]=max(f[j+ww*two[i]],f[j]+p*two[i]);
    19                 c-=two[i];
    20             }
    21           else break;
    22         for (int i=7; i>=0; i--)
    23           if (c>=two[i])
    24             {
    25                 for (int j=w-ww*two[i]; j>=0; j--)
    26                   f[j+ww*two[i]]=max(f[j+ww*two[i]],f[j]+p*two[i]);
    27                 c-=two[i];
    28             }
    29     }
    30     int ans=0;
    31     for (int i=1; i<=W; i++) ans=max(ans,f[i]);
    32     cout<<ans<<endl;
    33     return 0;
    34 }
    View Code

    附加题: 51Nod 1257

     

    N个物品的体积为W1,W2......Wn(Wi为整数),与之相对应的价值为P1,P2......Pn(Pi为整数),从中选出K件物品(K <= N),使得单位体积的价值最大。
    Input
    第1行:包括2个数N, K(1 <= K <= N <= 50000)
    第2 - N + 1行:每行2个数Wi, Pi(1 <= Wi, Pi <= 50000)
    Output
    输出单位体积的价值(用约分后的分数表示)。
    Input示例
    3 2
    2 2
    5 3
    2 1
    Output示例
    3/4


    看似是背包,其实否然。
    这题只需二分一下就可以了。二分单位体积的价值 p,然后设每个物品的 rate 为 w[i]-p*p[i],按 rate 从大到小排序,
    然后去最大的 k 个,如果最后的rate 之和大于0,那么说明 p 还能再大,否则 p 只能变小。

    代码:
     1 #include<bits/stdc++.h>
     2 #define LL long long
     3 using namespace std;
     4 const int maxn=50007;
     5 LL gcd(LL a,LL b) { return b==0?a:gcd(b,a%b); }
     6 int n,k;
     7 struct node{
     8     int w,p;
     9     double rate;
    10 }beg[maxn];
    11 bool cmp(node a,node b)
    12 {
    13     return a.rate>b.rate;
    14 }
    15 int resw,resp;
    16 int answ,ansp;
    17 bool check(double p)
    18 {
    19     resw=0;
    20     resp=0;
    21     double mark=0.0;
    22     for (int i=1; i<=n; i++)
    23       beg[i].rate=1.0*beg[i].p-beg[i].w*p;
    24     sort(beg+1,beg+1+n,cmp);
    25     for (int i=1; i<=k; i++)
    26     {
    27         resw+=beg[i].w;
    28         resp+=beg[i].p;
    29         mark+=beg[i].rate;
    30     }
    31     if (mark>=0) return true;
    32     return false;
    33 }
    34 int main()
    35 {
    36     scanf("%d%d",&n,&k);
    37     for (int i=1; i<=n; i++)
    38       scanf("%d%d",&beg[i].w,&beg[i].p);
    39     double l=0.0,r=50000;
    40     for (int i=0; i<=100; i++)
    41     {
    42         double mid=(l+r)/2;
    43         if (check(mid))
    44         {
    45             answ=resw;
    46             ansp=resp;
    47             l=mid;
    48         }
    49         else r=mid;
    50     }
    51     LL gg=gcd(answ,ansp);
    52     answ/=gg; ansp/=gg;
    53     printf("%d/%d
    ",ansp,answ);
    54     return 0;
    55 }
    View Code

    加油加油加油!!!fighting fighting fighting!!!

     
  • 相关阅读:
    springmvc项目搭建四-基于前端框架完善页面的数据显示
    springmvc项目搭建三-添加前端框架
    spring 配置问题记录1-@ResponseBody和favorPathExtension
    oracle定时job粗解
    oracle存储过程粗解
    springmvc maven搭建二之springmvc的security
    Oracle 数据库导出时 EXP-00008;ORA-00904
    搭建springmvc项目404,没扫描到包
    oracle基础概念学习笔记
    linux判断存储空间是否满
  • 原文地址:https://www.cnblogs.com/Frank-King/p/9313766.html
Copyright © 2011-2022 走看看