zoukankan      html  css  js  c++  java
  • HDU 2639 Bone Collector II (01背包,第k解)

    题意:

      数据是常规的01背包,但是求的不是最大容量限制下的最佳解,而是第k佳解。

    思路:

      有两种解法:

    1)网上普遍用的O(V*K*N)。

    2)先用常规01背包的方法求出背包容量限制下能装的最大价值m,再以m为背包容量再进行一次01背包,dp[j]表示当物品的组合价值为j时,它们的体积之和的最小量。那么就求出了所有可能的价值,从1~m都有,但是其中一些是求不出来的,也就是骨头的价值不能组合成这个数字,那么就得过滤掉。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <limits.h>
     5 using namespace std;
     6 int N, V, K, dp[1000000], w[105], v[105];
     7 
     8 void cal()
     9 {
    10     for(int i=0; i<N; i++)
    11     {
    12         for(int j=V; j>=v[i]; j--)
    13             dp[j] = max( dp[j], dp[j-v[i]]+w[i] );
    14     }
    15     if(K==1)
    16     {
    17         cout<<dp[V]<<endl;
    18         return ;
    19     }
    20     
    21     int m=dp[V];
    22     int flag=(1<<30)+(1<<29);
    23     dp[0]=0;
    24     for(int i=1; i<=m; i++)
    25         dp[i]=flag;
    26     
    27     for(int i=0; i<N; i++)
    28     {
    29         for(int j=m; j>=w[i]; j--)
    30         {
    31             if(dp[j-w[i]]<flag)
    32                 dp[j]=min(dp[j], dp[j-w[i]]+v[i]);
    33             
    34         }
    35     }
    36 
    37     int cnt=0;
    38     for(int i=m; i>0; i--)
    39     {
    40         if(dp[i]!=flag && dp[i]<=V )
    41         {
    42             cnt++;
    43             if(cnt==K)
    44             {
    45                 cout<<i<<endl;
    46                 return ;
    47             }
    48         }
    49     }
    50     cout<<"0"<<endl;
    51 }
    52 
    53 int main()
    54 {
    55     //freopen("input.txt","r",stdin);
    56     int t;
    57     cin>>t;
    58     while(t--)
    59     {
    60         memset(dp,0,sizeof(dp));
    61         cin>>N>>V>>K;
    62         for(int i=0; i<N; i++)
    63             cin>>w[i];
    64         for(int i=0; i<N; i++)
    65             cin>>v[i];
    66         cal();
    67 
    68     }
    69     return 0;
    70 }
    AC代码(第2种解法)
  • 相关阅读:
    使用ngx_lua构建高并发应用(1)
    nginx+lua项目学习
    学习乱
    if---(switch-case)语句初步学习总结
    数据类型转换
    总结:C#变量,占位符等相关知识
    学习随笔
    开始我的.NET的学习旅程
    Python 网络爬虫 008 (编程) 通过ID索引号遍历目标网页里链接的所有网页
    Python 网络爬虫 007 (编程) 通过网站地图爬取目标站点的所有网页
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4480730.html
Copyright © 2011-2022 走看看