AcWing 1020. 潜水员
原题链接
简单
作者:
总有刁民想害朕
,
2020-03-12 13:09:41
,
所有人可见
,
阅读 637
思路分析
一:首先需要明白本题问的是 体积至少为多少时,对于这样的问题,我们要想明白和法状态都包括什么样的
1:体积至少为j的最小重量 (j > 0) 合法
2:体积至少为j的最小重量 (j == 0) 合法 ,此时就等于0
3:体积至少为j的最小重量 (j < 0) 合法, 此时等价于 j == 0
二:分析完合法状态后,我们就要设计状态以及状态计算了
1:把枚举前i件物品作为阶段,把氧气和氮气的体积至少为 j 和 k 作为附加维度,至此一个状态就表示出来了,接下来考虑决策,和其他背包问题一样,就是选和不选第i件物品
2:想清楚每一维的枚举从大到小还是从小到大以及枚举范围到0还是其他,这里根据上面写的合法状态可以想清楚
C++ 代码
#include <bits/stdc++.h>
using namespace std;
const int N = 80, M = 1010;
struct thing{
int a, b, c;
};
vector<thing> things;
int dp[N][N];
int mn, mo;
int k;
int main(){
cin >> mo >> mn;
cin >> k;
for(int i = 0;i < k;++i){
int a, b, c;
cin >> a >> b >> c;
things.push_back({a, b, c});
}
memset(dp, 0x3f, sizeof dp);
dp[0][0] = 0;
for(int i = 0;i < things.size();++i)
for(int j = mo;j >= 0;--j)
for(int k = mn;k >= 0;--k)
dp[j][k] = min(dp[j][k], dp[max(0, j - things[i].a)][max(0, k - things[i].b)] + things[i].c);
cout << dp[mo][mn] << endl;
return 0;
}
我思故我在