整数划分
C++
整数划分
/* * 整数划分 * * 问题描述: * 题目: * 一个正整数 n 可以表示成若干个正整数之和,形如:n=n1+n2+…+nk,其中, n1 ≥ n2 ≥ … ≥ nk,k ≥ 1。 * 我们将这样的一种表示称为正整数 n 的一种划分。(其实上面这个定义主要是说明其有序性) * 现在给定一个正整数 n,请你求出 n 共有多少种不同的划分方法。 * * 数据范围: * 1 ≤ n ≤ 1000 * 求解思路1: * f[i][j] 表示 若干整数相加为 i,其中最大的正整数为 j,划分方法的次数 * 那么: f[i][j] = f[i - j][1] + f[i - j][2] + ... + f[i - j][min(i - j, j)] * 其中 min(i - j, j) 既是为了防止最大值超过 sum,也是为了防止最大值超过 j * 初始化时候 memset(f, 0, sizeof f), f[0][0] = 1即可。 * * 复杂度 O(N^3) * 求解思路2: * 不难发现求解思路1复杂度过高在于f[i][j] 的求解公式是一个 sum,因此我们可以重新定义 f[i][j]数组含义减少复杂度, * 或者是维护一个 sum 的累加和数组。 * 重新定义 f[i][j], 表示 若干整数相加为 i,其中最大的正整数 <= j,划分方法的次数 * 因此 * f[i][j] = f[i][j - 1] + f[i - j][min(i - j, j)] * 复杂度 O(N ^ 2) * 最后发现,这是完全背包解法 * 求解思路3: * f[i][j] 表示总和为 i,数组的长度为 j 的方案数 * f[i][j] = f[i - 1][j - 1] + f[i - 2][j - 1] + f[i - 3][j - 1] + ... + f[j - 1][j - 1] + ... + f[0][j - 1] * * 算法优化: f[i][j] 表示 总和小于等于 i,长度等于 j * f[i][j] = f[i - 1][j] + f[i-1][j-1] * * 初始化: * memset(f, 0, sizeof f); * f[0][0] = 1 * * 但是该方法是错误的,因为 f[i - 1][j - 1] + f[i - 2][j - 1] + f[i - 3][j - 1] + ... + f[j - 1][j - 1] + ... + f[0][j - 1] * 这些方案可能是存在交叉了。。。。 * * 重新划分,f[i][j]还是表示总和为 i,长度为 j * 存在 1 的方案个数为 f[i-1][j-1] * 不存在 1 的方案个数为 f[i-j][j] */ #include <iostream> #include <cstring> #include <string> #include <algorithm> #include <cstdio> #include <cmath> using namespace std; const int N = 1010, MOD = 1e9 + 7; int f[N][N], n; int solution_one() { // initial memset(f, 0, sizeof f); f[0][0] = 1; // dp loop for (int i = 1; i <= n; i ++ ) { for (int j = 1; j <= i; j ++ ) { // 注意这 min(i - j, j) f[i][j] = (f[i][j - 1] + f[i - j][min(i - j, j)]) % MOD; } } return f[n][n]; } int solution_two() { // initial memset(f, 0, sizeof f); f[0][0] = 1; // dp loop for (int i = 1; i <= n; i ++ ) { for (int j = 1; j <= i; j ++ ) { f[i][j] = (f[i - 1][j - 1] + f[i - j][j]) % MOD; } } int res = 0; for (int i = 1; i <= n; i ++ ) { res = (res + f[n][i]) % MOD; } res = (res % MOD + MOD) % MOD; return res; } int main() { // input scanf("%d", &n); int res = solution_two(); // output printf("%d\n", res); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)