0,1背包经典例题,限制体积的情况下,对每件物品选或者不选进而得到有限条件下的最大价值。
分析一个子问题,看题目,小孩只能选择从城堡中移除积木,即什么呢?
小孩可以从城堡中的积木中选择移除或者不移除,每一次的最大高度就是所有积木的总和,从这个子问题中可以看到0,1背包比较明显的特征。
1.有一个限制条件,即最大高度是所有积木的和。
2.每一个积木可以选择移除或者保留。
通过保存每一次状态转移中的高度,我们就可以得到每一个高度是否在某个城堡中被使用过,再这样的方式下,我们就可以通过统计每一个高度出现的次数,得出是否有一个高度满足所有城堡都能达到,并且最大。
#include <bits/stdc++.h>
using namespace std;
int a[1001], ans[100010];
typedef long long ll;
bool f[100010];
int main() {
int n;
cin >> n;
ll maxn = 0;
for (int i = 1; i <= n; i++) {
ll sum = 0;
memset(a, 0, sizeof(a));
memset(f, 0, sizeof(f));
int g = 0;
while (1) {
cin >> a[++g];
if (a[g] < 0)
break;
sum += a[g];
}
if (sum > maxn)
maxn = sum;
f[0] = 1;
for (int i = 1; i <= g; i++) {
for (int j = sum; j >= a[i]; j--) {
if (!f[j] && f[j - a[i]])
f[j] = 1, ans[j]++;//表示这个高度在这个城堡处已经被计算过一次,不需要再重复计算。
}
}
}
for (int i = maxn; i >= 0; i--) {
if (ans[i] == n) {
cout << i;
return 0;
}
}
cout << 0;
return 0;
}