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\n",dp[j],s[i].h);
                num[j]=num[j-s[i].h]+1;
                //if(dp[j]==37)
                //printf("%d\n",num[j]);
            }
        }
        int maxn=0;
        for(int i=0;i<=maxx;i++)
        if(maxn<dp[i])
        maxn=dp[i];
        printf("%d\n",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\n",maxx);
        sort(s+1,s+1+n,cmp);
        //for(int i=1;i<=n;i++)
        //printf("%d %d %d\n",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\n",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\n",dp[j]);
            }
        }
        int maxn=0;
        for(int i=0;i<=maxx;i++)
        if(maxn<dp[i])
        maxn=dp[i];
        printf("%d\n",maxn-1);
    }
    return 0;
}

 

posted @ 2013-07-26 12:44  紫忆  阅读(664)  评论(0编辑  收藏  举报