洛谷 P4141 一道比较有意思的背包
https://www.luogu.com.cn/problem/solution/P4141
要求输出在体积x的情况下不选择物品i的方案数目
不考虑删除物品有
\[dp[j] += dp[j-w[i]]
\]
我们发现当一个物品被选择时,他对\(dp[j]\)做出了\(dp[j-w[i]]\)的贡献,我们将这部分删去,得到的自然就是没有选择物品\(i\)的方案数了
不妨设\(g[j]\)表示当前不选择第\(i\)个物品的方案数,然也有状态转移方程
\[ g[j] =
\begin{cases}
dp[j] & j < w[i] \\
dp[j] - g[j-w[i]] & j \geq w[i]
\end{cases}
\]
对于每个物品 \(i\)我们只需要对其小到大枚举重量\(j\)即可
贴上代码
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2010;
int n, m, w[MAXN], dp[MAXN], g[MAXN];
int main()
{
ios::sync_with_stdio(0), cin.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; i++)
{
cin >> w[i];
}
dp[0] = 1;
for(int i = 1; i <= n; i++)
{
for(int j = m; j >= w[i]; j--)
{
dp[j] = (dp[j] + dp[j-w[i]]) % 10;
}
}
for(int i = 1; i <= n; i++)
{
g[0] = 1;
for(int j = 1; j <= m; j++)
{
if(j >= w[i]) g[j] = (dp[j] - g[j-w[i]] + 10) % 10;
else g[j] = dp[j];
printf("%d", g[j]);
}
printf("\n");
}
return 0;
}
浙公网安备 33010602011771号