传送门:https://www.luogu.com.cn/problem/P2079
容易知道,假如去掉
Σ
X
i
≥
0
\Sigma X_i\geq0
ΣXi≥0的条件,这题就是个赤裸裸的0/1背包
分析数据范围:
容易知道复杂度一定是O(fV),其中f是一个代数式
与此同时,我们注意到
X
i
X_i
Xi的绝对值不超过5,也就意味着
Σ
X
i
\Sigma X_i
ΣXi 的绝对值一定小于等于500
我们可以猜想:把Xi作为物品(即一道菜)的代价,最后统计答案时只统计满足
Σ
X
i
≥
0
\Sigma X_i\geq0
ΣXi≥0的方案
由于中间过程允许出现
Σ
X
i
<
0
\Sigma X_i<0
ΣXi<0的情况,开数组的时候应该开到两倍大小,保证不会出现负数下标。
大概框架:
for(register int i = 1; i <= n; ++i)
for(register int j = v; j >= c[i]; --j) { //倒序循环
//do something
}
尤其要注意的是,为了保证 Σ X i \Sigma X_i ΣXi这个维度上枚举未被更新的数据(即f[i-1][j][k]),对于 X i < 0 X_i<0 Xi<0的情况,我们必须正序循环。否则就会访问到已经更新的数据(f[i][j][k])
if(x[i] > 0)
for(register int k = 1000; k >= x[i]; --k) {
//?
dp[j][k] = max(dp[j][k], dp[j - c[i]][k - x[i]]);
}
else
for(register int k = 0; k <= 1000; ++k) {
//?
dp[j][k] = max(dp[j][k], dp[j - c[i]][k - x[i]];
}
其中?处应该填入能够保证所有方案合法的代码,譬如
if(d[j - c[i]][k - x[i]] == -1)continue;
处理边界条件是DP的重要环节!
处理边界条件是DP的重要环节!
处理边界条件是DP的重要环节!