zoukankan      html  css  js  c++  java
  • dp之多重背包poj2392

    题意:有k种石头,高为hi,在不超过ai的高度下,这种石头可以放置,有ci种这个石头,求这些石头所能放置的最高高度.........

    思路:以往的什么硬币种数,最大硬币数之类的,他们的硬币都已经是排好序了的,总是从小到大,但是这个题目不同,它有着最高高度的限制,那么在思考的时候,要得到最优的,那么首先就是要对ai排序......这是贪心,然后就是多重背包了........

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    struct node
    {
        int h;
        int a;
        int c;
    }s[500];
    int dp[50000],num[41000];
    int cmp(const node p,const node q)
    {
        return p.a<q.a;
    }
    int main()
    {
        int n;
        while(scanf("%d",&n)>0)
        {
            int maxx=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%d %d %d",&s[i].h,&s[i].a,&s[i].c);
                if(maxx<s[i].a)
                maxx=s[i].a;
            }
            sort(s+1,s+1+n,cmp);
            memset(dp,0,sizeof(dp));
            dp[0]=1;
            for(int i=1;i<=n;i++)
            {
                memset(num,0,sizeof(num));
                for(int j=s[i].h;j<=maxx;j++)
                if(dp[j-s[i].h]&&dp[j-s[i].h]+s[i].h>dp[j]&&dp[j-s[i].h]+s[i].h-1<=s[i].a&&num[j-s[i].h]<s[i].c)
                {
                    dp[j]=dp[j-s[i].h]+s[i].h;
                    //printf("%d %d
    ",dp[j],s[i].h);
                    num[j]=num[j-s[i].h]+1;
                    //if(dp[j]==37)
                    //printf("%d
    ",num[j]);
                }
            }
            int maxn=0;
            for(int i=0;i<=maxx;i++)
            if(maxn<dp[i])
            maxn=dp[i];
            printf("%d
    ",maxn-1);
        }
        return 0;
    }
    
    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    struct node
    {
        int h;
        int a;
        int c;
    }s[500];
    int dp[50000],c[5000][2];
    int cmp(const node p,const node q)
    {
        return p.a<q.a;
    }
    int main()
    {
        int n;
        while(scanf("%d",&n)>0)
        {
            int cnt=0,maxx=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%d %d %d",&s[i].h,&s[i].a,&s[i].c);
                if(maxx<s[i].a)
                maxx=s[i].a;
            }
            //printf("%d
    ",maxx);
            sort(s+1,s+1+n,cmp);
            //for(int i=1;i<=n;i++)
            //printf("%d %d %d
    ",s[i].h,s[i].a,s[i].c);
            for(int i=1;i<=n;i++)
            {
                int k=1;
                while(s[i].c-k>0)
                {
                    c[cnt][0]=k*s[i].h;
                    c[cnt++][1]=s[i].a;
                    s[i].c-=k;
                    k*=2;
                    //if(s[i].h==5)
                    //printf("%d %d
    ",c[cnt-1][0],c[cnt-1][1]);
                }
                c[cnt][0]=s[i].h*s[i].c;
                c[cnt++][1]=s[i].a;
            }
            memset(dp,0,sizeof(dp));
            dp[0]=1;
            for(int i=0;i<cnt;i++)
            {
                for(int j=maxx;j>=c[i][0];j--)
                if(dp[j-c[i][0]]&&dp[j-c[i][0]]+c[i][0]-1<=c[i][1]&&dp[j-c[i][0]]+c[i][0]>dp[j])
                {
                    dp[j]=dp[j-c[i][0]]+c[i][0];
                    //printf("%d
    ",dp[j]);
                }
            }
            int maxn=0;
            for(int i=0;i<=maxx;i++)
            if(maxn<dp[i])
            maxn=dp[i];
            printf("%d
    ",maxn-1);
        }
        return 0;
    }
    
  • 相关阅读:
    GSM和GPRS的区别
    IP规划和VLSM子网划分例题
    20190806-sed面试题
    yum.rpm一点点
    实验:基于http的yum源
    vim编辑二进制文件
    关于find的-perm
    误删tree命令如何恢复
    删除Linux的依赖库并进入救援模式恢复
    第六天、用户、组、权限、grep
  • 原文地址:https://www.cnblogs.com/ziyi--caolu/p/3216855.html
Copyright © 2011-2022 走看看