zoukankan      html  css  js  c++  java
  • 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;
            }
    }
  • 相关阅读:
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    449. Serialize and Deserialize BST
    114. Flatten Binary Tree to Linked List
    199. Binary Tree Right Side View
    173. Binary Search Tree Iterator
    98. Validate Binary Search Tree
    965. Univalued Binary Tree
    589. N-ary Tree Preorder Traversal
    eclipse设置总结
  • 原文地址:https://www.cnblogs.com/program-ccc/p/4705379.html
Copyright © 2011-2022 走看看