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

     该题目为求01背包中的第k最优解:
     开始时用dpp[i][j]表示用体积为i得到价值为j,WA了好多次,系统说是数组开的大小有问题
     应该定义数组dp[i][j][k]表示前i个物品中用体积j所得价值排名第k,类似于dp[i][j],
     该数组每次有两个方案可得,即dp[i-1][j][k]与dp[i-1][j-cost[i]][k]+value[i];
     用数组A及数组B分别保存数组dp[i-1][j][k]及数组dp[i-1][j-cost[i]][k]+value[i]的前k项,
     再对两个数组进行合并,赋值给dp[i][j][k],不过知道最优是k优的一种特殊情况了,代码如下:
    #include <iostream>
    #include <cstdio>
    #include <string.h>
    int dp[1005][35],value[1005],volume[1005],A[35],B[35];
    int main()
    {
        int t,n,i,j,k,v,kk,a,b,c;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d%d",&n,&v,&k);
            for (i=1;i<=n;++i)
            scanf("%d",&value[i]);
            for (i=1;i<=n;++i)
            scanf("%d",&volume[i]);
            memset(dp,0,sizeof(dp));
            for (i=1;i<=n;++i)
            for (j=v;j>=volume[i];--j)
            {
                for (kk=1;kk<=k;++kk)
                {
                    A[kk]=dp[j-volume[i]][kk]+value[i];//分类取前K大
                    B[kk]=dp[j][kk];
                }
                a=b=c=1;
                while(c<=k&&(a<=k||b<=k))//a<=k||b<=k表示还有没有取完的,该循环是对两个数组进行合并
                {
                    if (A[a]>B[b])
                    dp[j][c]=A[a],a++;
                    else
                    dp[j][c]=B[b],b++;
                    if (dp[j][c]!=dp[j][c-1])//即前后不相等,由前两个if判断条件可知dp数组以一定的顺序保存了
                    ++c;
                }
            }
            printf ("%d\n",dp[v][k]);
        }
        return 0;
    }
    
  • 相关阅读:
    【已解决】github中git push origin master出错:error: failed to push some refs to
    好记心不如烂笔头,ssh登录 The authenticity of host 192.168.0.xxx can't be established. 的问题
    THINKPHP 5.0目录结构
    thinkphp5.0入口文件
    thinkphp5.0 生命周期
    thinkphp5.0 架构
    Django template
    Django queryset
    Django model
    Python unittest
  • 原文地址:https://www.cnblogs.com/1994two/p/3068697.html
Copyright © 2011-2022 走看看