分享一下最近广航ACM集训队举办的蓝桥杯选拔赛的“整数拼凑问题”,并分享我的解法(仅供参考)。
问题描述
将给定的正整数 n 拆分为若干个正整数之和的方案个数问题,要求所有的拼凑方案不重复。如 n=5,则对应的不重复的拼凑方案如下,共有 7 种。
5=5
5=4+1
5=3+2
5=3+1+1
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1
请你计算:对于整数 n (0<n<=120),一共有多少种拼凑方案?
输入格式
一行一个整数 n
输出格式
一行一个结果,即拼凑方案数
输入样例
5
输出样例
7
解题思路
当n=1,只有1=1这1种,n=2时,有2=2和2=1+1这两种,n=3时,有3=3、3=2+1、3=1+1+1三种,n=4时,有4=4、4=3+1、4=2+2、4=2+1+1、4=1+1+1+1五种,我们把等号左边的数称为组合数,等号右边的数称为拆分数,为了试着找出规律,我们暂时先列出1个如下4乘4的矩阵a,第i行j列代表组合数为i且最大拆分数为j的拼凑方案,则第i行的数据之和就表示对于i的总拼凑方案
| i\j | 1 | 2 | 3 | 4 |
|---|---|---|---|---|
| 1 | 1 | 0 | 0 | 0 |
| 2 | 1 | 1 | 0 | 0 |
| 3 | 1 | 1 | 1 | 0 |
| 4 | 1 | 2 | 1 | 1 |
比如第3行2列为1,表示组合数为3且最大拆分数为2的拼凑方案只有1,即3=2+1。
易知拆分数最大只能是其组合数本身,所以这是个下三角矩阵,要想知道整数n有多少拼凑方案,只要将矩阵的第n行数据加起来就是了,即将n的最大值分别为1、2、3……n的拼凑方案加起来。
这就需要求第i行j列的数据,即组合数为i且最大拆分数为j的拼凑方案,已知最大拆分数为j则其余几项拆分数之和为 (i-j) ,所以第i行j列的数据等于第 (i-j) 行的第1列到第j列或第(i-j)列(较小列)的数据之和(i>j),除此之外还有一种较为特别的情况,即i=j时,不存在第i-j=0行,所以这里直接给所有i=j的数据赋为1,即n=n的那一种拼凑方案,而i<j的情况前面已经讲过拆分数最大只能是其组合数本身,所以直接是0。
综上,a[i] [j]={
1,i=j
0,i<j
a[i-j] [1]+a[i-j] [2]+a[i-j] [3]+……+a[i-j] [i-j],i-j<=j
a[i-j] [1]+a[i-j] [2]+a[i-j] [3]+……+a[i-j] [j],i-j>j
},由这个公式我们便能算出这整个矩阵,也就可以算出整数n有多少拼凑方案了
代码
#include"stdio.h"
int main(){
int n,a[121][121]={0},an=0;
scanf("%d",&n);
int i,j;
a[1][1]=1;
for(i=2;i<=n;i++){
for(j=1;j<=i;j++){
for(int k=1;k<=i-j&&k<=j;k++){
a[i][j]+=a[i-j][k];
}
}
a[i][i]=1;
}
for(int i=1;i<=n;i++){
an+=a[n][i];
}
printf("%d",an);
return 0;
}
整数拼凑问题解析与算法实现
这篇博客分享了ACM集训队蓝桥杯选拔赛中的整数拼凑问题,详细介绍了如何计算给定整数n的不同拼凑方案数。博主通过列举和分析不同数值的拼凑情况,发现并解释了其中的规律,并给出了递推公式。最后,博主提供了C++代码实现,用于计算120以内整数的拼凑方案数。
1141

被折叠的 条评论
为什么被折叠?



