• poj 1014多重背包


    题意:给出价值为1,2,3,4,5,66种物品数量,问是否能将物品分成两份,使两份的总价值相等。

    思路:求出总价值除二,做多重背包,需要二进制优化。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    int n[7];
    int v,sum;
    bool flag;
    int dp[100000];
    
    /*完全背包*/
    void CompletePack(int cost,int weight)
    {
    	for(int i=cost;i<=v;i++)
    	{
    		dp[i]=max(dp[i],dp[i-cost]+weight);
    		if(dp[i]==v)    //剪枝
    		{
    			flag=true;
    			return;
    		}
    	}
    
    	return;
    }
    /*01背包*/
    void ZeroOnePack(int cost,int weight)
    {
    	for(int i=v;i>=cost;i--)
    	{
    		dp[i]=max(dp[i],dp[i-cost]+weight);
    		if(dp[i]==v)    //剪枝
    		{
    			flag=true;
    			return;
    		}
    	}
    	return;
    }
    
    /*多重背包*/
    void MultiplePack(int cost,int weight,int amount)
    {
    	if(cost*amount>=v)
    	{
    		CompletePack(cost,weight);
    		return;
    	}
    
    	if(flag)    //剪枝
    		return;
    
    	/*二进制优化*/
    	int k=1;
    	while(k<amount)
    	{
    		ZeroOnePack(k*cost,k*weight);
    
    		if(flag)
    			return;
    
    		amount-=k;
    		k*=2;
    	}
    	ZeroOnePack(amount*cost,amount*weight);
    
    	return;
    }
    
    int main(int i)
    {
    	int test=1;
    	while(scanf("%d%d%d%d%d%d", &n[1], &n[2], &n[3], &n[4], &n[5], &n[6])!=EOF)
        {
    		sum=0;  //物品总价值
    
    		for(i=1;i<=6;i++)
    			sum+=i*n[i];
    
    		if(sum==0)
    			break;
    
    		if(sum%2)
    		{
    			cout<<"Collection #"<<test++<<':'<<endl;
    			cout<<"Can't be divided."<<endl<<endl;
    			continue;
    		}
    
    		v=sum/2;
    		memset(dp,-1,sizeof(dp));
    		dp[0]=0;
    		flag=false;
    
    		for(i=1;i<=6;i++)
    		{
    			MultiplePack(i,i,n[i]);
    
    			if(flag)    //剪枝
    				break;
    		}
    
    		if(flag)
    		{
    			cout<<"Collection #"<<test++<<':'<<endl;
    			cout<<"Can be divided."<<endl<<endl;
    			continue;
    		}
    		else
    		{
    			cout<<"Collection #"<<test++<<':'<<endl;
    			cout<<"Can't be divided."<<endl<<endl;
    			continue;
    		}
    		printf("
    ");
    	}
    	return 0;
    }
    


     

  • 相关阅读:
    11.28 正则表达式
    12.28jQuery 的取值赋值
    11.27 上传下载 图片预览
    11.28 验证控件
    12.23,repeater 分页显示
    12.23,搜索标记
    1.基础CRUD
    C#杀进程与之之子进程
    使用procedump捕获未处理异常的dump
    [.net core] 12.环境变量
  • 原文地址:https://www.cnblogs.com/amourjun/p/5134115.html
Copyright © 2020-2023  润新知