1.整数二次幂拆分
1.1题目描述:
题目描述
一个整数总可以拆分为2的幂的和,例如: 7=1+2+4 7=1+2+2+2 7=1+1+1+4 7=1+1+1+2+2 7=1+1+1+1+1+2 7=1+1+1+1+1+1+1 总共有六种不同的拆分方式。 再比如:4可以拆分成:4 = 4,4 = 1 + 1 + 1 + 1,4 = 2 + 2,4=1+1+2。 用f(n)表示n的不同拆分的种数,例如f(7)=6. 要求编写程序,读入n(不超过1000000),输出f(n)%1000000000。
输入描述:
每组输入包括一个整数:N(1<=N<=1000000)。
输出描述:
对于每组数据,输出f(n)%1000000000。
示例1
输入
7
输出
6
1.2.基本思路
定义规划数组dp[N],其中dp[i]=f(i),可以等到如下递推方程:
①当i为奇数的时候,dp[i]只需在dp[i-1]的所有情况上加上1即可
②当i为偶数的时候,dp[i]有两部分组成,
—1>拆分后的整数中包含1,
d
p
[
i
−
1
]
dp[i-1]
dp[i−1]种
—2>拆分后的整数中不包含1,
d
p
[
i
2
]
dp[\frac{i}{2}]
dp[2i]种
1.3.代码实现
/**
采用动态规划的方法求解,分两种情况考虑
①当i为奇数的时候
dp[i]=dp[i-1]
②当i为偶数的时候
dp[i]=dp[i-1]+dp[i/2]
其中dp[i-1]表示拆解的整数中含有1的情况
dp[i/2]表示拆解的整数中不含有1的情况
*/
#include <iostream>
#define N 1000001
using namespace std;
int buf[N];
int main()
{
int n;
while(cin>>n){
for(int i=1;i<=n;i++){
if(i==1)
buf[i]=1;
else if(i%2!=0)
buf[i]=buf[i-1];
else
buf[i]=(buf[i-1]+buf[i/2])%1000000000;
}
cout<<buf[n]<<endl;
}
return 0;
}
2.整数拆分
2.1题目描述:
将给定正整数n表示成一些列整数的之和, n = n 1 + n 2 + . . . + n k n=n_1+n_2+...+n_k n=n1+n2+...+nk,其中n_1≥n_2≥…≥n_k≥1,k≥1.求正整数n的不同划分个数p(n)
例如:
6;
5+1;
4+2, 4+1+1;
3+3, 3+2+1, 3+1+1+1;
2+2+2, 2+2+1+1, 2+1+1+1+1;
1+1+1+1+1+1;
2.2.基本思路
该问题具有比较明显的递归关系,因而容易采用递归的函数进行求解。而在该问题中递归的关系不太明显,p(n)为整数n的划分数,则比较难以找到递归的关系,因此需要增加一个自变量:将最大数n不大于m的划分个数记为q(n,m).可以建立如下递推关系式:
对于n>m>1这种情况比较难于理解:
分为以下两种情况:
所以n>m>1的时候得到公式:
q
(
n
,
m
)
=
q
(
n
,
m
−
1
)
+
q
(
n
−
m
,
m
)
q(n,m)=q(n,m-1)+q(n-m,m)
q(n,m)=q(n,m−1)+q(n−m,m)
2.3.代码实现
#include <iostream>
using namespace std;
int q(int n,int m){
if(n==1&&m==1)
return 1;
else if(m>n){
return q(n,n);
}
else if(m==n){
return 1+q(n,n-1);
}
else if(m>=1&&m<n){//
return q(n,m-1)+q(n-m,m);
}
else{
return 0;
}
}
int main()
{
int n;
while(cin>>n){
cout<<q(n,n)<<endl;
}
return 0;
}
参考博客:https://blog.csdn.net/u011889952/article/details/44813593