洛谷 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;
}
posted @ 2025-07-24 15:43  东东哥本人  阅读(6)  评论(0)    收藏  举报