• HDOJ1059(多重背包)


    1.解法一:多重背包

    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define MAX(a,b) (a>b)?a:b
    const int SIZE=500000+16;
    int dp[SIZE];
    int bag[7];
    int nLimit;
    
    void ZeroOnePack(int cost, int value)
    {
        for(int i=nLimit; i>=cost; i--)
            dp[i]=MAX(dp[i],dp[i-cost]+value);
    }
    
    void CompletePack(int cost, int value)
    {
        for(int i=cost; i<=nLimit; i++)
            dp[i]=MAX(dp[i],dp[i-cost]+value);
    }
    
    void MultiplyPack(int cost, int value, int amount)
    {
        if(amount*cost>=nLimit) CompletePack(cost,value);
        else
        {
            int k=1;
            while(k<amount)
            {
                ZeroOnePack(k*cost, k*value);
                amount-=k;
                k<<=1;
            }
            
            ZeroOnePack(amount*cost,amount*value);
        }
    }
    
    bool CheckFinish()
    {
        for(int i=1;i<=6;i++)
            if(bag[i]!=0)
                return false;
        return true;
    }
    
    int main()
    {
        int T=0;
        while(true)
        {
            int sum=0;
            for(int i=1; i<=6; i++)
            {
                scanf("%d",&bag[i]);
                sum+=bag[i]*i;
            }
            if(CheckFinish())
                break;
                
            printf("Collection #%d:
    ",++T);
            if(sum%2==1)
            {
                printf("Can't be divided.
    ");
            }
            else
            {
                memset(dp,0,sizeof(dp));
                nLimit=sum/2;
                for(int i=1;i<=6;i++)
                {
                    MultiplyPack(i,i,bag[i]);
                }
                if(dp[nLimit]==nLimit)
                    printf("Can be divided.
    ");
                else
                    printf("Can't be divided.
    ");
            }
            printf("
    ");
            
        }
    
        return 0;
    }

    2.解法二:多重部分和

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int SIZE=120000+16;
    int a[6];
    int dp[SIZE];
    bool check()
    {
        for(int i=0;i<6;i++)
            if(a[i]!=0)
                return true;
        return false;
    }
    int sum;
    
    int main()
    {
        int t=0;
        while(true)
        {
            sum=0;
            for(int i=0;i<6;i++)
            {
                scanf("%d",&a[i]);
                sum+=(i+1)*a[i];
            }
            if(!check())
                break;    
            
            printf("Collection #%d:
    ",++t);    
            if(sum%2==1)
            {
                printf("Can't be divided.
    ");
            }
            else
            {
                memset(dp,-1,sizeof(dp));
                int k=sum/2;
                dp[0]=0;
                for(int i=0;i<6;i++)
                {    
                    for(int j=0;j<=k;j++)
                    {
                        if(dp[j]>=0)
                        {
                            dp[j]=a[i];
                        }
                        else if(j<(i+1)||dp[j-(i+1)]<=0)
                        {
                            dp[j]=-1;    
                        }
                        else
                        {
                            dp[j]=dp[j-(i+1)]-1;
                        }            
                    }
                }
                if(dp[k]>=0)
                {
                    printf("Can be divided.
    ");
                }
                else
                {
                    printf("Can't be divided.
    ");
                }
            }
            printf("
    ");
        }
        return 0;
    }

     3.解法三:判断多重背包可否装满

    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define MAX(a,b) (a>b)?a:b
    const int SIZE=500000+16;
    const int INF=100000;
    int dp[SIZE];
    int bag[7];
    int nLimit;
    bool CheckFinish()
    {
        for(int i=1;i<=6;i++)
            if(bag[i]!=0)
                return false;
        return true;
    }
    
    int main()
    {
        int T=0;
        while(true)
        {
            int sum=0;
            for(int i=1; i<=6; i++)
            {
                scanf("%d",&bag[i]);
                sum+=bag[i]*i;
            }
            if(CheckFinish())
                break;
                
            printf("Collection #%d:
    ",++T);
            if(sum%2==1)
            {
                printf("Can't be divided.
    ");
            }
            else
            {
                nLimit=sum/2;
                memset(dp,0,sizeof(dp));
                dp[0]=1;
                int dpt[120000];
                for(int i=1;i<=6;i++)
                {
                    memset(dpt,0,sizeof(dpt));
                    for(int j=i;j<=nLimit;j++)
                        if(!dp[j]&&dp[j-i]&&dpt[j-i]<bag[i])
                        {
                            dpt[j]=dpt[j-i]+1;
                            dp[j]=1;
                        }
                }
                
                if(dp[nLimit])
                {
                    printf("Can be divided.
    ");
                }
                else
                {
                    printf("Can't be divided.
    ");
                }
            }
            
            printf("
    ");
        }
    
        return 0;
    }

    判断模板:
     

    memset(dp,0,sizeof(dp));
    dp[0]=1;
    int used[120000];
    for(int i=1;i<=nKind;i++)
    {
        memset(used,0,sizeof(used));
        for(int j=weight[i];j<=nLimit;j++)
            if(!dp[j]&&dp[j-weight[i]]&&used[j-weight[i]]<bag[i])
            {
                used[j]=used[j-weight[i]]+1;
                dp[j]=1;
            }
    }
  • 相关阅读:
    Maven_自动化构建和构建环节
    Maven_运行时环境
    构建的概念
    Maven_真的需要吗?
    28)拷贝构造函数
    27)构造和析构函数
    26)多文件形式编写类步骤
    25)类的封装
    24)类
    23)函数重载和函数指针
  • 原文地址:https://www.cnblogs.com/program-ccc/p/4705379.html
Copyright © 2020-2023  润新知