九度1084解题报告
2014-03-05 20:41
232 查看
http://ac.jobdu.com/problem.php?pid=1084 整数拆分的题。
根据这几天的做清华真题的情况,可以看出,清华超爱出数学类的题目,考察学生的数学基础和找规律的能力。这道题,乍一看是要找个什么公式或者规律来解决,其实仅仅用dp就可以解决,也就是说,要找出拆分种类的递推规律。本题主要有两条规律,即要分奇偶讨论。
当要拆分的数为奇数时,其拆分种类与上一个偶数相同,其实就是在上一个数的各拆分上+1,我一开始怀疑,如果原拆分中也含1,将两个1换成一个2,会不会又是一种新的拆分,事实上不会,因为偶数的拆分中1一定是成对出现的,如果新加的1与原来的一个1凑成一对,那么把多出来的一个单1去掉,一定是上一个偶数的一个拆分。因此,一个奇数的拆分与它上一个偶数的拆分一定一样多。这个规律比较明显。
而当要拆分的数为偶数时,规律就比较难找了。上一个奇数的各拆分加1肯定构成新的拆分,而上一个奇数的带不成对1 的拆分,与新加的1凑成一对,也构成新的拆分,进而不断向上凑,很难得出有多少拆分。于是,我们考虑另一种分类方法:将拆分分为带1的拆分和不带1的拆分。不带1的拆分,最小数为2,故整个拆分可以被2整除,因此数n不带1的拆分数应该和n/2的所有拆分相等。而带1的拆分,其实和上一个奇数相同,因为带1的拆分至少有两个1,去掉一个1后,即n-1的拆分。
找到了规律,用dp就很方便了,代码如下:
根据这几天的做清华真题的情况,可以看出,清华超爱出数学类的题目,考察学生的数学基础和找规律的能力。这道题,乍一看是要找个什么公式或者规律来解决,其实仅仅用dp就可以解决,也就是说,要找出拆分种类的递推规律。本题主要有两条规律,即要分奇偶讨论。
当要拆分的数为奇数时,其拆分种类与上一个偶数相同,其实就是在上一个数的各拆分上+1,我一开始怀疑,如果原拆分中也含1,将两个1换成一个2,会不会又是一种新的拆分,事实上不会,因为偶数的拆分中1一定是成对出现的,如果新加的1与原来的一个1凑成一对,那么把多出来的一个单1去掉,一定是上一个偶数的一个拆分。因此,一个奇数的拆分与它上一个偶数的拆分一定一样多。这个规律比较明显。
而当要拆分的数为偶数时,规律就比较难找了。上一个奇数的各拆分加1肯定构成新的拆分,而上一个奇数的带不成对1 的拆分,与新加的1凑成一对,也构成新的拆分,进而不断向上凑,很难得出有多少拆分。于是,我们考虑另一种分类方法:将拆分分为带1的拆分和不带1的拆分。不带1的拆分,最小数为2,故整个拆分可以被2整除,因此数n不带1的拆分数应该和n/2的所有拆分相等。而带1的拆分,其实和上一个奇数相同,因为带1的拆分至少有两个1,去掉一个1后,即n-1的拆分。
找到了规律,用dp就很方便了,代码如下:
#include <stdio.h> #define MAX 1000002 #define MOD 1000000000 long long dp[MAX]; int main() { dp[0]=dp[1]=1; for (int i=1;i<=500000;++i) { dp[2*i]=(dp[2*i-1]+dp[i])%MOD; dp[2*i+1]=dp[2*i]%MOD; } int n; while (scanf("%d",&n)!=EOF) { printf("%lld\n", dp ); } return 0; }
相关文章推荐
- 九度OJ 1087 约数的个数解题报告
- 【九度OJ】题目1202:排序 解题报告
- 九度的《剑指Offer:名企面试官精讲典型编程题》 面试题 解题报告
- 【九度OJ】题目1078:二叉树遍历 解题报告
- 【九度OJ】题目1138:进制转换 解题报告
- 【九度OJ】题目1442:A sequence of numbers 解题报告
- 【九度OJ】题目1178:复数集合 解题报告
- 【九度OJ】题目1192:回文字符串 解题报告
- 【九度OJ】题目1061:成绩排序 解题报告
- 【九度OJ】题目1065:输出梯形 解题报告
- 【九度OJ】题目1445:How Many Tables 解题报告
- 【九度OJ】题目1182:统计单词 解题报告
- 【九度OJ】题目1193:矩阵转置 解题报告
- 【九度OJ】题目1185:特殊排序 解题报告
- 【九度OJ】题目1083:特殊乘法 解题报告
- 【九度OJ】题目1194:八进制 解题报告
- 【九度OJ】题目1163:素数 解题报告
- 【九度OJ】题目1198:a+b 解题报告
- 【九度OJ】题目1205:N阶楼梯上楼问题 解题报告
- 九度OJ1099:后缀子串排序解题报告