当前位置: 首页 > news >正文

整数划分问题

整数划分是将一个正整数n表示为一系列正整数之和的问题。顺序不同的划分视为相同的划分。这是一个经典的组合数学和计算机科学问题。

1. 问题定义

将正整数n表示为:
n = a₁ + a₂ + ... + aₖ (aᵢ ≥ 1, 1 ≤ i ≤ k)

其中划分的顺序不重要,即 3+2 和 2+3 被视为相同的划分。

2. 递推关系

设 p(n, m) 表示将整数n划分成最大加数不超过m的划分个数。

递推关系:

  • p(n, 1) = 1 (只有全1的划分)

  • p(1, m) = 1 (只有1本身)

  • p(n, m) = p(n, n) 当 m > n

  • p(n, m) = p(n, m-1) + p(n-m, m) 当 n > m ≥ 1

3. C语言实现

方法一:递归实现

#include <stdio.h>// 递归计算整数划分
int partition_recursive(int n, int m) {if (n < 1 || m < 1) return 0;if (n == 1 || m == 1) return 1;if (n < m) return partition_recursive(n, n);if (n == m) return 1 + partition_recursive(n, m - 1);return partition_recursive(n, m - 1) + partition_recursive(n - m, m);
}int main() {int n;printf("请输入要划分的整数 n: ");scanf("%d", &n);printf("整数 %d 的划分数: %d\n", n, partition_recursive(n, n));return 0;
}

方法二:动态规划

#include <stdio.h>
#include <stdlib.h>// 动态规划计算整数划分
int partition_dp(int n) {if (n <= 0) return 0;int **dp = (int**)malloc((n + 1) * sizeof(int*));for (int i = 0; i <= n; i++) {dp[i] = (int*)malloc((n + 1) * sizeof(int));}// 初始化for (int i = 0; i <= n; i++) {for (int j = 0; j <= n; j++) {if (i == 0 || j == 0) {dp[i][j] = 0;} else if (i == 1 || j == 1) {dp[i][j] = 1;} else if (i < j) {dp[i][j] = dp[i][i];} else if (i == j) {dp[i][j] = 1 + dp[i][j - 1];} else {dp[i][j] = dp[i][j - 1] + dp[i - j][j];}}}int result = dp[n][n];// 释放内存for (int i = 0; i <= n; i++) {free(dp[i]);}free(dp);return result;
}int main() {int n;printf("请输入要划分的整数 n: ");scanf("%d", &n);printf("整数 %d 的划分数: %d\n", n, partition_dp(n));return 0;
}

方法三:优化的动态规划(一维数组)

#include <stdio.h>
#include <stdlib.h>// 优化的动态规划(使用一维数组)
int partition_dp_optimized(int n) {if (n <= 0) return 0;int *dp = (int*)malloc((n + 1) * sizeof(int));// 初始化dp[0] = 1;  // 空划分算一种for (int i = 1; i <= n; i++) {dp[i] = 0;}// 动态规划计算for (int i = 1; i <= n; i++) {for (int j = i; j <= n; j++) {dp[j] += dp[j - i];}}int result = dp[n];free(dp);return result;
}int main() {int n;printf("请输入要划分的整数 n: ");scanf("%d", &n);printf("整数 %d 的划分数: %d\n", n, partition_dp_optimized(n));return 0;
}

4. 输出所有划分

#include <stdio.h>
#include <stdlib.h>// 输出所有整数划分
void print_partitions(int n, int max, int *arr, int index) {if (n == 0) {// 找到一个划分,输出for (int i = 0; i < index; i++) {printf("%d", arr[i]);if (i < index - 1) printf(" + ");}printf("\n");return;}for (int i = max; i >= 1; i--) {if (n >= i) {arr[index] = i;print_partitions(n - i, i, arr, index + 1);}}
}int main() {int n;printf("请输入要划分的整数 n: ");scanf("%d", &n);int *arr = (int*)malloc(n * sizeof(int));printf("整数 %d 的所有划分:\n", n);print_partitions(n, n, arr, 0);free(arr);return 0;
}

5. 计算并输出所有划分(带计数)

#include <stdio.h>
#include <stdlib.h>int count = 0;// 输出所有划分并计数
void print_and_count_partitions(int n, int max, int *arr, int index) {if (n == 0) {count++;printf("%d: ", count);for (int i = 0; i < index; i++) {printf("%d", arr[i]);if (i < index - 1) printf(" + ");}printf("\n");return;}for (int i = max; i >= 1; i--) {if (n >= i) {arr[index] = i;print_and_count_partitions(n - i, i, arr, index + 1);}}
}int main() {int n;printf("请输入要划分的整数 n: ");scanf("%d", &n);int *arr = (int*)malloc(n * sizeof(int));count = 0;printf("整数 %d 的所有划分:\n", n);print_and_count_partitions(n, n, arr, 0);printf("总划分数: %d\n", count);free(arr);return 0;
}

6. 完整测试程序

#include <stdio.h>
#include <stdlib.h>
#include <time.h>// 递归方法
int partition_recursive(int n, int m) {if (n < 1 || m < 1) return 0;if (n == 1 || m == 1) return 1;if (n < m) return partition_recursive(n, n);if (n == m) return 1 + partition_recursive(n, m - 1);return partition_recursive(n, m - 1) + partition_recursive(n - m, m);
}// 动态规划方法
int partition_dp(int n) {if (n <= 0) return 0;int **dp = (int**)malloc((n + 1) * sizeof(int*));for (int i = 0; i <= n; i++) {dp[i] = (int*)malloc((n + 1) * sizeof(int));}for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {if (i == 1 || j == 1) {dp[i][j] = 1;} else if (i < j) {dp[i][j] = dp[i][i];} else if (i == j) {dp[i][j] = 1 + dp[i][j - 1];} else {dp[i][j] = dp[i][j - 1] + dp[i - j][j];}}}int result = dp[n][n];for (int i = 0; i <= n; i++) {free(dp[i]);}free(dp);return result;
}// 优化的动态规划
int partition_dp_optimized(int n) {if (n <= 0) return 0;int *dp = (int*)malloc((n + 1) * sizeof(int));dp[0] = 1;for (int i = 1; i <= n; i++) {dp[i] = 0;}for (int i = 1; i <= n; i++) {for (int j = i; j <= n; j++) {dp[j] += dp[j - i];}}int result = dp[n];free(dp);return result;
}int main() {int n;printf("整数划分问题测试\n");printf("请输入要划分的整数 n: ");scanf("%d", &n);if (n <= 0) {printf("请输入正整数\n");return 1;}printf("\n方法比较:\n");// 测试递归方法(只适用于小n)if (n <= 30) {clock_t start = clock();int result_rec = partition_recursive(n, n);clock_t end = clock();double time_rec = ((double)(end - start)) / CLOCKS_PER_SEC;printf("递归方法: %d (耗时: %.6f秒)\n", result_rec, time_rec);} else {printf("递归方法: n太大,跳过计算\n");}// 测试动态规划clock_t start = clock();int result_dp = partition_dp(n);clock_t end = clock();double time_dp = ((double)(end - start)) / CLOCKS_PER_SEC;printf("动态规划: %d (耗时: %.6f秒)\n", result_dp, time_dp);// 测试优化的动态规划start = clock();int result_opt = partition_dp_optimized(n);end = clock();double time_opt = ((double)(end - start)) / CLOCKS_PER_SEC;printf("优化动态规划: %d (耗时: %.6f秒)\n", result_opt, time_opt);return 0;
}

7. 编译和运行

bash 复制 下载

gcc integer_partition.c -o integer_partition
./integer_partition

8. 算法分析

方法时间复杂度空间复杂度适用场景
递归O(2ⁿ)O(n)小规模数据 (n < 30)
动态规划O(n²)O(n²)中等规模数据
优化动态规划O(n²)O(n)推荐,适合大多数情况

http://www.dtcms.com/a/532995.html

相关文章:

  • 做电子商务网站需要学什么php 网站 整合 数据库
  • 【车载测试常见问题】CAN总线错误帧的常见触发情况
  • 第一ppt模板网站深圳品牌营销推广
  • 国外网站大牛不懂英语可以做吗wordpress热点插件
  • 04、数字电路与 C 语言基础
  • 【代码】八数码难题模板 [宽搜]
  • 震惊!这家滑雪租赁服务商竟让千万用户疯狂抢订!
  • JSP技术入门指南十IDEA开发环境下MySQL数据可视化展示与前后端交互实战
  • 网站建设的思想静态html怎么部署到服务器
  • 餐饮网站建设的目的如何制作境外网站
  • [nanoGPT] configurator.py | exec() globals()
  • 【瑞芯微】【rk3128】【01.使用docker搭建rk3128 编译烧录环境】
  • 企业官网网站优化公司现在网站给源码
  • 知春路网站建设网站建设网络推广柯
  • 002-Spring AI Alibaba Prompt 功能完整案例
  • 网站栏目设计优化方案驾校网站源码下载
  • 大模型-模型压缩:量化、剪枝、蒸馏、二值化 (2)
  • 做文章网站汕尾建设网站首页
  • 数据结构<C++>——链表
  • 数据结构-并查集
  • 该如何建设和优化一个网站网页设计与制作工资多少
  • 建设自己的网站有什么wordpress radiate
  • Peppa Pig - Gardening
  • 蒙文门户网站建设淘宝seo搜索优化工具
  • html基本标签
  • 肇庆网站制作软件枫林seo
  • 网站地址申请极简网站模板
  • 《首屏加载优化手册:Vue3+Element Plus项目提速的技术细节》
  • typora1.9.5安装与激活
  • 自适应网站模板企业网站建设一般步骤