题意就是求满足 氧气 和 氮气 需求的情况下最少背的气缸重量。
样例:
因为每个气缸只能有选和不选两种状态(看样例看出来的,不是因为他善。那么我们就可以把这个问题转换为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]);
}
}
}
点个赞(: