9 ACwing 279 自然数拆分Lunatic版 题解

自然数拆分Lunatic版

题面

给定一个自然数 \(N\) ,要求把 \(N\) 拆分成若干个正整数相加的形式,参与加法运算的数可以重复

  • 拆分方案不考虑顺序;
  • 至少拆分成 2 个数的和。

求拆分的方案数 \(\bmod 2^{31}\) 的结果

\(1 \le N \le 4000\)

题解

完全背包板子,设 \(f(i,j)\) 表示考虑前 \(i\) 个数,从中选若干个,可以重复,和为 \(j\) 的方案数

转移 \(f(i,j) += f(i - 1, j - i)\) ,同样可以优化掉第一维,时间复杂度 \(O(N^2)\) ,内层循环正序枚举即可

code

注意一下 unsigned int 的范围是 \(0 \sim 2^{32} - 1\) 所以不能用溢出取模,要手动取模

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>

using namespace std;

const int N = 4010;
const unsigned int mod = 2147483648u;

int n;
unsigned int f[N];

int main () {
    cin >> n;
    f[0] = 1;
    
    for (int i = 1; i < n; i++) {
        for (int j = i; j <= n; j ++) {
            f[j] += f[j - i];
            f[j] %= mod;
        }
    }

    cout << f[n] << endl;

    return 0;
}
posted @ 2025-10-05 17:59  michaele  阅读(7)  评论(0)    收藏  举报