题解【AcWing279】自然数拆分
标签(空格分隔): DP 背包
题面
因为题目中说参与加法运算的数可以重复,由此可以想到完全背包计数问题。
完全背包计数问题与 \(01\) 背包计数问题只有一个不同: \(01\) 背包计数问题的第二维循环是倒叙循环,而完全背包计数问题的第二维循环是正序循环。
这涉及到的是循环时后效性的问题,具体的证明留给读者思考。
注意每一步计数都要取模,且最后输出要减去只有 \(n\) 一个数的一组解。
#include <bits/stdc++.h>
#define DEBUG fprintf(stderr, "Passing [%s] line %d\n", __FUNCTION__, __LINE__)
#define itn int
#define gI gi
using namespace std;
typedef long long LL;
typedef pair <int, int> PII;
typedef pair <int, PII> PIII;
inline int gi()
{
int f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return f * x;
}
const int maxn = 4003;
int n;
LL dp[maxn];
int main()
{
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
n = gi();
dp[0] = 1;
for (int i = 1; i <= n; i+=1)
{
for (int j = i; j <= n; j+=1)
{
(dp[j] += dp[j - i]) %= (1ll * 2147483648);
}
}
printf("%lld\n", (dp[n] - 1) % (1ll * 2147483648));
return 0;
}
原文地址:https://www.cnblogs.com/xsl19/p/12303844.html
时间: 2024-10-01 07:05:00