SCUBADIV - Scuba diver 题解
题目大意
潜水员有
给出潜水员所需要的氧气量和氮气量,求所需气缸的总重的最低限度是多少。
解题思路
对于每个气缸,有两种不同的费用:氧气和氮气,需要满足这两个条件,才能得到价值,也就是气缸的重量;所以可以看作是二维费用的背包问题。
将每个气缸的质量看做物品,把气缸的总重的最低限度看做背包。
枚举每个气缸,每次做二维费用的背包,如果当前的氧气或氮气超过了所需要的氧气或氮气,可以直接用需求量代替。
二维费用的背包:
划分阶段:
- 以当前的氧气瓶为阶段;
状态表达:
- 设
表示当所需的氧气量为 ,氮气量为 的时候气缸的最小重量;
状态转移:
-
当不选第
个气缸时,不变, ; -
当选第
个气缸时,减去当前的氧气和氮气,加上质量, ; -
这里注意,当
或 小于零时,也就是选中当前的氧气和氮气后还有剩余的氧气和氮气,这种情况可以直接用 或 ,所以可以特判一下,如果 或 小于零, 或 等于 。
初始状态:
- 因为当所需的氧气量为
,氮气量为 的时候气缸的最小重量也是 ,所以 ;要取最小值,所以其余全部为 ;
求解目标:
代码
最后输出不加换行会 WA!
#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int INF=0x3f;
int q;
int main() {
cin>>q;
while(q--) {
int n,m,idx;
cin>>n>>m>>idx;
int o[1005],d[1005],w[1005],f[25][80];
for(ri i=1; i<=idx; i++)
cin>>o[i]>>d[i]>>w[i];
memset(f,INF,sizeof(f));
f[0][0]=0;//初始状态
for(ri i=1; i<=idx; i++)//阶段
for(ri j=n; j>=0; j--)//氧气
for(ri k=m; k>=0; k--) {//氮气
int x=j-o[i],y=k-d[i];
if(x<0)x=0;
if(y<0)y=0;
f[j][k]=min(f[j][k],f[x][y]+w[i]);
}
cout<<f[n][m]<<'\n';//求解目标
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】