普及2 T5潜水员(ID:7185) 题解

题意就是求满足 氧气 和 氮气 需求的情况下最少背的气缸重量。

样例:
样例输入与输出

因为每个气缸只能有选和不选两种状态(看样例看出来的,不是因为他善。那么我们就可以把这个问题转换为01背包了,先来看一下模板:

for(int i=1;i<=n;i++){//w是重量,v是价值
	for(int j=m;j>=w[i];j--){//为保证无后效性所以倒着来
		f[j]=max(f[j],f[j-w[i]]+v[i]);//滚动数组优化的状态转移方程
	}
}

什么是无后效性

但相较于模板还是要做许多改动的:

不难看出此时题目中两个气体(a[i],b[i])的两就是重量,而c[i]就是价值,所以我们要

  • 在模板的基础上加一维重量来表示每个状态,f[i][j]表示氧气为i,氮气为j时的最小重量

题目要求的是最小值所以我们还需初始化

memset(f,800,sizeof(f));//全部设为MAX_c[i]见题目数据范围
f[0][0]=0;//特殊的,啥也不拿当然是0啦

之后就可以爆改模板了:

for(int i=1;i<=k;i++){
	for(int j1=m;j1>=0;j1--){
		for(int j2=n;j2>=0;j2--){
			/*如果取的话下标(重量)为:*/int t1=j1+a[i] ,t2=j2+b[i];
			f[t1][t2]=min(f[t1][t2],f[j1][j2]+c[i]);//取和不取求最小重量
		}
	}
}	

然后你就RE 或 WA 啦!!
为什么呢?
因为不能保证t1,t2为正数,即保证 j1+a[i]<m&&j2+b[i]<n
所以下标还要与上限(m,n)取最小值:

int t1=min(j1+a[i],m) ,t2=min(j2+b[i],n);

正解如下:

for(int i=1;i<=k;i++)cin>>a[i]>>b[i]>>c[i];
	for(int i=1;i<=k;i++){
		for(int j1=m;j1>=0;j1--){
			for(int j2=n;j2>=0;j2--){
				int t1=min(j1+a[i],m) ,t2=min(j2+b[i],n);
				f[t1][t2]=min(f[t1][t2],f[j1][j2]+c[i]);
			}
		}
	}	

点个赞(:

11 个赞

@谢岂梵1 @阚宇阳 @范博文1 给我点赞 :heart:

8 个赞

为你点赞(虽然我看不懂)

5 个赞

@七濑胡桃 还有你

3 个赞