背包问题(未完成)

背包问题

  • 挑东西的问题

01背包_选与不选的问题

  • 循环变量从大到小,避免重复(否则将变成完全背包)
  • f[N]表示的是在N的资源下达成的结果,这里的N的资源并不是处在all in的状态,而是可以允许闲置的状态。
  • 当前的状态从何而来?一般是消耗一定的资源来换取一定的成果。
  • 有些题目存在开启条件,如278. 数字组合,所有的数字起源都来自于0,要令f[0]=1,从而通过f[0]=1来初始化其他的数字

1024.装箱问题

有一个箱子容量为 V,同时有 n 个物品,每个物品有一个体积(正整数)。

要求 n 个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

  • 尽可能拉大体积
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int V;
	int n;
	cin>>V>>n;
	int f[V+1],v;
	memset(f,0,sizeof(f));
	for(int i=1;i<=n;i++)
	{
		cin>>v;
		for(int j=V;j>=v;j--)
		{
			f[j]=max(f[j],f[j-v]+v);
		}
	}
	cout<<V-f[V];
	return 0;
}

278. 数字组合

给定 N个正整数 A1,A2,…,AN,从中选出若干个数,使它们的和为 M,求有多少种选择方案。

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n,m;
	cin>>n>>m;
	int f[m+1];
	memset(f,0,sizeof(f));
	f[0]=1;
	for(int i=0;i<n;i++)
	{
		int x;
		cin>>x;
		for(int j=m;j>=x;j--)
		    f[j]=f[j]+f[j-x];
	}
	cout<<f[m];
	return 0;
}

完全背包_选多和选少的问题

二维费用的背包问题_站在01背包的肩上

  • f[状态类型1]变成f[状态类型1][状态类型2]

8. 二维费用的背包问题

#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
int main()
{
	int N,VOL,WEI;
	cin>>N>>VOL>>WEI;
	int vol,wei,val;
	int f[VOL+1][WEI+1];
	memset(f,0,sizeof(f));
	for(int i=0;i<N;i++)
	{
		cin>>vol>>wei>>val;
		for(int j=VOL;j>=vol;j--)
		    for(int k=WEI;k>=wei;k--)
		    {
		    	f[j][k]=max(f[j][k],f[j-vol][k-wei]+val);
			}
	}
	cout<<f[VOL][WEI]<<endl;	
	return 0;
}

其他

并查集加背包

搭配购买

#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
int f[N];
struct article{
	int money;
	int val;
}a[N];
int find(int x)
{
	if(f[x]==x) return x;
	else return f[x] = find(f[x]);
}

int main()
{
	int n,m,w;
	cin>>n>>m>>w;
	map<int,article > counter;
	
	for(int i=1;i<=n;i++)
	{ 
	    cin>>a[i].money>>a[i].val;
		f[i] = i;	
	}
	 
	for(int i=0;i<m;i++)
	{
		int c1,c2;
		cin>>c1>>c2;
		int f1=find(c1),f2=find(c2);
		if(f1!=f2)
           f[f1]=f2;	
	}
	
	map <int ,int > fpos;
	int cost[n+1],value[n+1],f[w+1],cnt=0;
	memset(f,0,sizeof(f));
	for(int i=1;i<=n;i++)
	{
		int ffa=find(i);
		if(fpos.count(ffa)==0)
		    fpos[ffa]=cnt,cost[cnt]=a[i].money,value[cnt]=a[i].val,cnt++;
		else cost[fpos[ffa]]+=a[i].money,value[fpos[ffa]]+=a[i].val;
	}

    for(int i=0;i<cnt;i++)
    {
    	for(int j=w;j>=cost[i];j--)
    	    f[j]=max(f[j-cost[i]]+value[i],f[j]);
	}
	cout<<f[w];
	return 0;
}
原文地址:https://www.cnblogs.com/BeautifulWater/p/15012580.html