• 背包模板整理


    背包问题主要是背模板,这里收录了一些模板

    一些复杂的背包问题(如泛化物品)未收录

    01背包问题:

    无优化

    for(int i=1;i<=n;i++)
    {
        for(int c=0;c<=m;c++)
        {
            f[i][c]=f[i-1][c];
            if(c>=w[i])
            f[i][c]=max(f[i][c],f[i-1][c-w[i]]+v[i]);
        }
    }
    

      

    一维数组优化:

    for(int i=1;i<=n;i++)
    {
        for(int c=m;c>=0;c--)
        {
            if(c>=w[i])
            f[c]=max(f[c],f[c-w[i]]+v[i]);
        }
    }
    

      

    更进一步的常数优化:

    for(int i=1;i<=n;i++)
    {
        sumw+=w[i];
        bound=max(m-sumw,w[i]);
        for(int c=m;c>=bound;c--)
        {
            if(c>=w[i])
            f[c]=max(f[c],f[c-w[i]]+v[i]);
        }
    }
    

      

    完全背包问题:

    for(int i=1;i<=n;i++)
    {
        for(int c=0;c<=m;c++)
        {
            if(c>=w[i])
            f[c]=max(f[c],f[c-w[i]]+v[i]);
        }
    }
    

      

    多重背包问题:

    for(int i=1;i<=n;i++)
    	for(int j=m;j>=1;j--)
    		for(int k=0;k<=c[i];k++)
    		{
    			if(dp[j]-k*s[i]<0)
    				break;
    			dp[j]=max(dp[j],dp[j-k*s[i]]+k*c[i]);
    		}
    

      其实三种背包的区别在于数量的多少

      所谓的01背包就是只能取一次,而完全背包是可以去无数次,多重背包对于每一件物品的数量有一个限定,所以我们要加入一个特判 

    	if(dp[j]-k*s[i]<0)
    				break;
    

      没有什么技巧可言,对于数组的建立也是取决于个人喜好

    下面是几道背包的例题(版子)

    http://ybt.ssoier.cn:8088/problem_show.php?pid=1267

     这是01背包的版子

    #include<iostream>
    #include<cstdio>
    #include<math.h>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxm=201,maxn=31;
    int m,n;
    int w[maxn],c[maxn];
    int dp[maxm];
    int main()
    {	
    	cin>>m>>n;
    	for(int i=1;i<=n;i++)
    		cin>>w[i]>>c[i];
    	for(int i=1;i<=n;i++)
    		for(int j=m;j>=w[i];j--)
    		dp[j]=max(dp[j],dp[j-w[i]]+c[i]);
    		cout<<dp[m];
    	return 0;
    }
    

    http://ybt.ssoier.cn:8088/problem_show.php?pid=1268 

     

     完全背包的版子

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define itn int
    
    using namespace std;
    int dp[10000],w[10000],c[10000];
    itn n,m;
    
    int main()
    {
    	cin>>m>>n;
    	for(int i=1;i<=n;i++)
    	{
    		cin>>w[i]>>c[i];
    	}
    	for(int i=1;i<=n;i++)
    		for(itn j=w[i];j<=m;j++)
    		dp[j]=max(dp[j],dp[j-w[i]]+c[i]);
    	cout<<"max="<<dp[m]<<endl;
    	return 0; 
    }
    

      http://ybt.ssoier.cn:8088/problem_show.php?pid=1269

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define itn int
    #define q 10000
    using namespace std;
    int dp[q],c[q],w[q],v[q];
    int n,m;
    
    int main()
    {
    	cin>>n>>m;
    	for(int i=1;i<=n;i++)
    		cin>>w[i]>>c[i]>>v[i];//价格 价值 数量 
    	for(int i=1;i<=n;i++)
    		for(int j=m;j>=0;j--)	
    			
    			for(itn k=0;k<=v[i];k++)
    			{if(j-k*w[i]<0) break;
    			dp[j]=max(dp[j],dp[j-k*w[i]]+k*c[i]);	}
    	cout<<dp[m];
    	return 0;
    }
    

    http://ybt.ssoier.cn:8088/problem_show.php?pid=1270  

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define itn int
    #define q 10000
    using namespace std;
    itn f[q],w[q],c[q],v[q];
    int main()
    {
    	int m,n;
    	cin>>m>>n;
    	for(int i=1;i<=n;i++)
    	cin>>w[i]>>c[i]>>v[i]; 
    	for(int i=1;i<=n;i++)
    		{if(v[i]==0)
    		{
    			for(itn j=w[i];j<=m;j++)
    			f[j]=max(f[j],f[j-w[i]]+c[i]);
    		}
    		else 
    		for(itn j=1;j<=v[i];j++)
    			for(itn k=m;k>=w[i];k--)
    			f[k]=max(f[k],f[k-w[i]]+c[i]);
    	}
    	cout<<f[m];
    	return 0;
    }
    

      最后的混合背包意思是对于物品的拿取的数量还是有要求的,有的可以无限拿(完全背包) 有的只能拿一次(01背包)

    还有的只能拿指定的数量(多重背包)

    对于混合背包 我们只需要对于他的数量进行判断({if(v[i]==0)) 那么便是完全背包;else 便是01或是多重(BB一句对于01背包 我们可以看做是这些都是只能取一次的多重背包,所以他们是一类)

  • 相关阅读:
    Tomcat部署项目
    正则表达式
    文件的上传和下载
    实现扫码登陆
    onepill Android端
    部署SpringBoot到阿里云
    Gson
    HTML自动刷新页面
    Spring Data JPA根据属性名查询
    Spring Date JPA实现增删改查
  • 原文地址:https://www.cnblogs.com/--840-114/p/12937491.html
Copyright © 2020-2023  润新知