【算法笔记】 背包DP④ 二维费用背包(二维01背包)

1.简单模板例题(选自洛谷)

俗话说的好:“知己知彼,百战不殆”。L国的指挥官想派出间谍前往I国,于是,选人工作就落到了你身上。

你现在有N个人选,每个人都有这样一些数据:A(能得到多少资料)、B(伪装能力有多差)、C(要多少工资)。已知敌人的探查间谍能力为M(即去的所有人B的和要小于等于M)和手头有X元钱,请问能拿到多少资料? ##p1910

显然,这里有两个背包,B为第一个背包B,C为第二个背包,A为价值,每个物品也有两种属性,那么应该如何解决呢?

01背包是这么写的:f[j]=max(f[j],f[j-v[i]]+w[i])

那么,我们也只需要加一维即可:f[i][j]=max(f[i][j],f[i-v1[i]][j-v2[i]]+w[i])

那么就给出代码吧:

做法和01背包类似:

#include
using namespace std;
int n,m,x;
int a[10000]={};
int b[10000]={};
int c[10000]={};
int f[5000][5000]={};
int main()
{
	cin>>n>>m>>x;
	for (int i=1;i<=n;i++)
	    cin>>a[i]>>b[i]>>c[i];
	for (int i=1;i<=n;i++)
	    for (int j=m;j>=b[i];j--)
	        for (int k=x;k>=c[i];k--)
	            f[j][k]=max(f[j][k],f[j-b[i]][k-c[i]]+a[i]);
	cout<

2.求最小二维费用背包

潜水员为了潜水要使用特殊的装备。他有一个带2种气体的气缸:一个为氧气,一个为氮气。让潜水员下潜的深度需要各种的数量的氧和氮。潜水员有一定数量的气缸。每个气缸都有重量和气体容量。潜水员为了完成他的工作需要特定数量的氧和氮。他完成工作所需气缸的总重的最低限度的是多少?   例如:潜水员有5个气缸。每行三个数字为:氧,氮的(升)量和气缸的重量:

  3 36 120

  10 25 129

  5 50 250

  1 45 130

  4 20 119

如果潜水员需要5升的氧和60升的氮则总重最小为249 (1,2或者4,5号气缸)。 你的任务就是计算潜水员为了完成他的工作需要的气缸的重量的最低值。 

显然,这道题思路和之前的题目一样:

在状态的含义上有所差距:f[i][j]表示大于等于i的氧气和大于等于j的氮气的最小值

当我们去枚举i的时候,用j和k枚举和i处于同一个背包的另外的体积,最后求一下最小值即可

初始化:f[0][0]=0


#include
using namespace std;
int T,A,n,ans=999999999;
int w[5000]={};
int t[5000]={};
int a[5000]={};
int f[500][500]={};//f[i][j]表示大于等于i的氧气和大于等于j的氮气的最小值 
int main()
{
	memset(f,100,sizeof(f));
	f[0][0]=0;//初始化 
	cin>>T>>A>>n; 
	for (int i=1;i<=n;i++)
	    cin>>t[i]>>a[i]>>w[i];
	for (int i=1;i<=n;i++)
	    for (int j=T;j>=0;j--)//枚举和第i件物品放在一起的氧气的体积 
		    for (int k=A;k>=0;k--)//氮气的体积 
			{
				int Y=j+t[i];//表示该背包的氧气的体积 
				int D=k+a[i]; //氮气的体积
				Y=min(Y,T);
				D=min(D,A);//因为要把最后的结果控制在f[n][m]以内,所以把超出的视为f[n][m]
				f[Y][D]=min(f[Y][D],f[j][k]+w[i]);//表示第i件物品放和不放的最大值 
			}
	cout<<f[T][A];
	return 0;
}


你可能感兴趣的:(【算法笔记】 背包DP④ 二维费用背包(二维01背包))