• HDU 2639(01背包第K大)


    http://acm.hdu.edu.cn/showproblem.php?pid=2639

    http://blog.csdn.net/lulipeng_cpp/article/details/7584981

    求第K大的思路是把每个d[v]看成是由d[v]和d[v-cost]+weight两个序列组成的,然后分别记录每个序列的第k大,然后逐项更新。

    用个形象的比喻吧:如果我想知道学年最高分,那么,我只要知道每个班级的最高分,然后统计一遍就可以了。

    如果我想知道学年前十呢?我必须要知道每个班的前十名。大家在心里模拟一下,对,这就是本题核心的算法。两种决策,就可以看作这个学年只有两个班。

    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    using namespace std;
    
    #define MEM(a,b) memset(a,b,sizeof(a))
    #define pf printf
    #define sf scanf
    #define debug printf("!/n")
    #define INF 1000
    #define MAX(a,b) a>b?a:b
    #define blank pf("
    ")
    #define LL long long
    
    int dp[INF][50];
    
    int ci[INF];
    int wi[INF];
    
    int A[50];
    int B[50];
    
    
    int main()
    {
              int n,V,i,j,v,t,K,k;
    
              sf("%d",&t);
              while(t--)
              {
                        sf("%d%d%d",&n,&V,&K);
    
                        MEM(dp,0);
                        MEM(ci,0);
                        MEM(wi,0);
                        MEM(A,0);
                        MEM(B,0);
    
                        for(i = 1;i<=n;i++)
                        {
                                  sf("%d",&wi[i]);
                        }
    
                        for(i = 1;i<=n;i++)
                        {
                                  sf("%d",&ci[i]);
                        }
    
                        int a,b,c;
    
                        for(i = 1;i<=n;i++)
                        {
                                  for(v = V;v>=ci[i];v--)
                                  {
                                            for(k = 1;k<=K;k++)
                                            {
                                                      A[k] = dp[v][k];
                                                      B[k] = dp[v-ci[i]][k]+wi[i];
                                            }
    
                                            A[K+1] = B[K+1] = -1;
                                            a = b = c = 1;
    
                                            while(c<=K && (A[a] != -1 || B[b] != -1))
                                            {
                                                      if(A[a]>B[b])
                                                      {
                                                                dp[v][c] = A[a];
                                                                ++a;
                                                      }
                                                      else
                                                      {
                                                                dp[v][c] = B[b];
                                                                ++b;
                                                      }
                                                      
    
                                                      if(dp[v][c] != dp[v][c-1])
                                                                ++c;
                                            }
                                  }
                        }
    
                        pf("%d
    ",dp[V][K]);
              }
        return 0;
    }
  • 相关阅读:
    《编写高质量代码Web前端开发修炼之道》(读书笔记) windrainpy
    jQuery琐碎笔记 windrainpy
    【记录】事件冒泡和事件捕获 windrainpy
    JS比较容易迷惑的几个地方 windrainpy
    【转】成为顶级程序员的唯一途径! windrainpy
    jquery键盘事件 windrainpy
    【转】IE绝对定位元素神秘消失或被遮挡的解决 windrainpy
    简单算法
    HTTP的状态
    css的兼容问题
  • 原文地址:https://www.cnblogs.com/qlky/p/5039386.html
Copyright © 2020-2023  润新知