zoukankan      html  css  js  c++  java
  • HDU 2639 Bone Collector II

    题目大意:

    给出n,V,k,分别表示n个物品,体积为V,求第k大背包

    Sample Input
    3 5 10 2 1 2 3 4 5 5 4 3 2 1 5 10 12 1 2 3 4 5 5 4 3 2 1 5 10 16 1 2 3 4 5 5 4 3 2 1
    Sample Output
    12 2 0
    N <= 100 , V <= 1000 , K <= 30
    f[i][j][k]表示1~i物品,体积为j的第k大背包
    显然第一维可以滚掉
    显然f[i][j] [1..K]这K个数是由大到小排列的,所以我们把它认为是一个有序队列
    所以f[i][j]可以认为由f[i-1][j][1..k]与f[i-1][j-v[i]][1..k]合并得到
    取两个队列的前k大的值
    用归并排序就行了
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int n,V,k;
    int w[1001],v[1001],f[5001][51],a[51],b[51],c[51],ans;
    int main()
    {int i,j,l,r,p,T;
      cin>>T;
     while (T--)
     {
       cin>>n>>V>>k;
       for (i=1;i<=n;i++)
         scanf("%d",&w[i]);
       for (i=1;i<=n;i++)
         scanf("%d",&v[i]);
       memset(f,0,sizeof(f));
      int cur=0;
      for (i=1;i<=n;i++)
        {
          for (j=V;j>=v[i];j--)
        {
          for (l=1;l<=k;l++)
            {
              a[l]=f[j][l];
              b[l]=f[j-v[i]][l]+w[i];
            }
          l=1;r=1;p=1;a[k+1]=-1;b[k+1]=-1;
          while (p<=k&&(l<=k||r<=k))
            {
              if (a[l]>b[r])
            {
              f[j][p]=a[l];
              l++;
            }
              else 
            {
              f[j][p]=b[r];
              r++;
            }
              if (f[j][p]!=f[j][p-1]) p++;
            }
        }
        }
      cout<<f[V][k]<<endl;
    }
    }
  • 相关阅读:
    [算法]位运算问题之二
    [算法]位运算问题之一
    [算法]海量数据问题之二
    [算法]海量数据问题之一
    [算法]旋转词问题
    [算法]去掉字符串中连续出现的k个0子串
    [算法]字符串中数字子串的求和
    [算法]字符串之变形词问题
    Linux常用命令
    数据库中的事物
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7565500.html
Copyright © 2011-2022 走看看