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

    这题和典型的01背包求最优解不同,是要求第k优解,所以,最直观的想法就是在01背包的基础上再增加一维表示第k大时的价值。
    具体思路见下面的参考链接,说的很详细

    参考连接:
    http://laiba2004.blog.163.com/blog/static/8835120220138611342496/
    http://hi.baidu.com/chenyun00/item/1c6c44318acc8bfaa88428c7

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    const int maxn=101;
    const int maxv=1001;
    const int maxk=31;
    int n,v,k;
    int dp[maxv][maxk];  //dp[j][k]表示容量为j时,第k大的值
    int w[maxn];  //价值
    int vv[maxn];  //容量
    //一开始tmp只开了maxk个大小,导致WA。。。因为对应的每个k,有dp[j][z]和dp[j-vv[i]][z]+w[i]两个状态,所以要开2*maxk大小
    //int tmp[maxk*2];
    int tmp1[maxk*2];
    int tmp2[maxk*2];
    int main()
    {
        int t,idx,cnt;
        scanf("%d",&t);
        while(t--){
            scanf("%d%d%d",&n,&v,&k);
            for(int i=1;i<=n;i++)
                scanf("%d",&w[i]);  //价值
            for(int i=1;i<=n;i++)
                scanf("%d",&vv[i]); //容量
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=n;i++){
                for(int j=v;j>=vv[i];j--){
                    //idx=0;
                    for(int z=1;z<=k;z++){
                        tmp1[z]=dp[j][z];
                        tmp2[z]=dp[j-vv[i]][z]+w[i];
                    }
                    /*
                    sort(tmp+1,tmp+idx+1);
                    cnt=1;
                    dp[j][1]=tmp[idx];
                    for(int q=idx-1;q>=1&&cnt<k;q--){
                        if(tmp[q]!=tmp[q+1])
                            dp[j][++cnt]=tmp[q];
                    }
                    while(cnt<k){
                        dp[j][++cnt]=0;
                    }
                    */
                    //其实不需要按照上面用排序,可以用开两个数组tmp1和tmp2存储,这两个数组都是有序序列
                    //这样的话,从原本的931ms减少到125ms
                    tmp1[k+1]=-1;tmp2[k+1]=-1; //将tmp1和tmp2的第k+1个元素设为-1,即设成较小的值
                    int a=1,b=1;
                    cnt=0;
                    while(cnt<k && (a!=k+1||b!=k+1)){
                        if(tmp1[a]>tmp2[b]){
                            dp[j][++cnt]=tmp1[a];
                            a++;
                        }
                        else{
                            dp[j][++cnt]=tmp2[b];
                            b++;
                        }
                        if(dp[j][cnt]==dp[j][cnt-1])
                            cnt--;
                    }
    
                }
    
            }
            printf("%d
    ",dp[v][k]);
        }
        return 0;
    }
  • 相关阅读:
    数据结构(2)
    python数据结构(1)
    python 中__getitem__ 和 __iter__ 的区别
    python 中的 %s,%r,__str__,__repr__
    python中的zip
    python反射,单例模式
    类python中高级用法
    python中super与成员属性
    python 类与对象解析
    【其他】BootCDN
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/3460288.html
Copyright © 2011-2022 走看看