zoukankan      html  css  js  c++  java
  • hdu 2639 Bone Collector II (背包问题 第K优解)

    与一般的背包问题不同,要求的是第K优解,首先,我们要搞清楚的一个问题就是最优解是怎么求出来的。

    对于求最优解的情况,我们对每一种状态只保存了该状态下的最优解,忽略了其他解,进而实现状态之间的转移,而对于求第K优解的情况呢?其实只需要保存每一种状态下的前K优解,从这K个状态进行状态间的转移,同时去重,保存当前状态的K优解即可。

    #include<iostream>
    #include<algorithm>
    #include<set>
    using namespace std;
    int v[101],w[101];
    int n,m,k,dp[1010][31];
    int tmp[65];
    bool cmp(int a,int b)
    {
    	return a>b;
    }
    int main()   
    {
    	int cas;
        scanf("%d",&cas);
        while(cas--)
        {
            scanf("%d %d %d",&n,&m,&k);
            for(int i=0;i<n;i++)
                scanf("%d",&w[i]);
            for(int i=0;i<n;i++)
                scanf("%d",&v[i]);
    		memset(dp,0,sizeof(dp));
    		for(int i=0;i<n;i++)
    		{
    			for(int j=m;j>=v[i];j--)
    			{
    				int temp=0;
    				for(int t=0;t<k;t++)
    				{
    					tmp[temp++]=dp[j][t];
    					tmp[temp++]=dp[j-v[i]][t]+w[i];
    				}
    				//tmp数组保存该状态的所有可能解,再去重,求出k优解
    				sort(tmp,tmp+k*2,cmp);
    				temp=1;
    				dp[j][0]=tmp[0];
    				for(int t=1;t<k*2 && temp<k;t++)
    				{
    					if(tmp[t]!=tmp[t-1])
    						dp[j][temp++]=tmp[t];
    				}
    			}
    		}
    		printf("%d\n",dp[m][k-1]);
        }
        return 0;
    }
    
  • 相关阅读:
    磁盘分区,fdisk,gdisk,开机自动挂载,swap分区,修复文件系统,备份文件
    进程脱离窗口运行,僵尸、孤儿进程
    top命令、kill命令
    进程状态
    rpm包、挂载、yum命令
    DRF源码分析
    forms组件源码
    Django CBV源码分析
    魔法方法
    鸭子类型
  • 原文地址:https://www.cnblogs.com/nanke/p/2269103.html
Copyright © 2011-2022 走看看