zoukankan      html  css  js  c++  java
  • hdu 2639 (第k小的01背包)

    题意:第k小的01背包,重复的选项算一个

    分析:01背包问题,只考虑到第i个问题的各个体积的最优解,而第k大的01背包则需要更多的选项,有个博客举了这样一个例子

    我们年纪一共10个班,如果我想知道年纪第一,我需要知道每个班级的第一名,一比较,那么我就知道年纪第一是谁了

    如果我要知道年纪前十名,那么,我只要知道每个班的前10名,那么我比较之后就知道了年级的前十名

    dp[i][j]表示体积为i时,价值为第j大的价值,每次选择物品的时候,计算出所有的体积,把前k名按照顺序插入到dp[i]中,这样,最后得到答案dp[n][v]

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e3+5;
    
    int dp[maxn][35],v[105],w[105],A[35],B[35];
    
    int main(){
        int n,V,t,k;
        scanf("%d",&t);
        while(t--){
            scanf("%d%d%d",&n,&V,&k);
            for(int i=1;i<=n;i++)
                scanf("%d",v+i);
            for(int i=1;i<=n;i++)
                scanf("%d",w+i);
            memset(dp,0,sizeof(dp));
    
            int a,b,c,kk;
    
            for(int i=1;i<=n;i++)
                for(int j=V;j>=w[i];j--){
                    for(kk=1;kk<=k;kk++){
                        A[kk]=dp[j][kk];
                        B[kk]=dp[j-w[i]][kk]+v[i];
                    }
                    A[kk]=B[kk]=-1;
                    a=b=c=1;
    
                    while(c<=k&&(A[a]!=-1||B[b]!=-1)){
                        if(A[a]>B[b])
                            dp[j][c]=A[a++];
                        else
                            dp[j][c]=B[b++];
                        if(dp[j][c]!=dp[j][c-1])
                            c++;
                    }
                }
            printf("%d
    ",dp[V][k]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    iOS数字媒体开发浅析
    Servlet
    Qt之图形(绘制文本)
    Qt之图形(转换)
    asp.net 缓存公共类
    logback.xml
    ext树菜单实体类
    ext,exrReturn新增,修改删除等用
    ExtPager ,分页
    ExtGridReturn ,存放ext的实体类集合和总数
  • 原文地址:https://www.cnblogs.com/jihe/p/5225482.html
Copyright © 2011-2022 走看看