hdu 2639

6 篇文章 0 订阅
#include <stdio.h>
#define N 102
#define M 1002
int a[N], b[N], k, heap[M][31], hsize[M],c[33];
inline void merge(int a[], int an, int w, int b[], int &bn )
{
    int cn = 0, i=1, j=1, d=0;
    while( i<=an&&j<=bn&&d<k) if( a[i]+w == b[j] )i++;
        else if(a[i]+w>b[j]) c[++d]=a[i++]+w;
        else c[++d]=b[j++];
    while(i<=an&&d<k) c[++d]=a[i++]+w;
    while(j<=bn&&d<k) c[++d]=b[j++];
    for( i=1; i<=d; i ++ ) b[i]=c[i];
    bn=d;
}
int main()
{
    int cas, V, n, i, j,sum;
    scanf("%d",&cas);
    while( cas-- )
    {
        scanf("%d%d%d",&n,&V,&k);
        for(i=0; i<n; i++) scanf("%d",&a[i]);
        for(i=0; i<n; i++) scanf("%d",&b[i]);
        for(i=1; i<=V; i++ ) hsize[i] = 0;
        hsize[0]=1;
        heap[0][1]=sum=0 ;
        for(i=0; i<n; i ++  )
        {
            sum=b[i]+sum<V?b[i]+sum:V;
            for(j=sum; j >= b[i]; j -- )
            if( hsize[j-b[i]]>0 )
                merge(heap[j-b[i]],hsize[j-b[i]],a[i],heap[j],hsize[j]);
        }
        for(i=V-1;i>=1;i-- ) merge(heap[i],hsize[i],0,heap[V],hsize[V]);
        if(hsize[V]<k) puts("0");
        else printf("%d\n",heap[V][k]);
    }
    return 0;
}

堆实现

#include <stdio.h>
#define N 102
#define M 1002
int a[N], b[N], k, heap[M][31], hsize[M];
void keep_heap( int heap[], int s, int u )
{
    int x = u, l = u<<1, r = u<<1|1;
    if( l<=s && heap[x] > heap[l] ) x = l;
    if( r<=s && heap[x] > heap[r] ) x = r;
    if( x != u )
    {
        l = heap[x],heap[x]=heap[u],heap[u]=l;
        keep_heap(heap,s,x);
    }
}
void insert_heap( int heap[31], int &s, int x )
{
    if( s == k && x <= heap[1] ) return;
    for( int i = 1; i <= s; i ++ )
        if( x == heap[i] ) return ;
    if( s<k )
    {
        heap[++s] = x;
        for( int u = s; u>1 && heap[u]<heap[u/2]; u/=2 )
        x = heap[u], heap[u] = heap[u/2], heap[u/2] = x;
    }
    else if( s == k && heap[1]<x )
    {
        heap[1] = x;
        keep_heap(heap,s,1);
    }
}
int main()
{
    int cas, V, n, i, j,t,sum;
    scanf("%d",&cas);
    while( cas-- )
    {
        scanf("%d%d%d",&n,&V,&k);
        for(i=0; i<n; i++) scanf("%d",&a[i]);
        for(i=0; i<n; i++) scanf("%d",&b[i]);
        for(i=1; i<=V; i++ ) hsize[i] = 0;
        hsize[0]=1;
        heap[0][1]=sum=0 ;
        for(i = 0; i < n; i ++  )
        {
            sum=b[i]+sum<V?b[i]+sum:V;
            for(j=sum; j >= b[i]; j -- )
            if( hsize[j-b[i]]>0 )
                for(t = hsize[j-b[i]]; t>=1; t-- )
                insert_heap(heap[j],hsize[j],heap[j-b[i]][t]+a[i]);
        }
        for(i=V-1;i>=1;i-- )
        for(j=hsize[i];j>=1; j-- )
        insert_heap(heap[V],hsize[V],heap[i][j]);
        if(hsize[V]<k) puts("0");
        else printf("%d\n",heap[V][1]);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值