码迷,mamicode.com
首页 > 其他好文 > 详细

51nod p1201 整数划分

时间:2016-03-07 20:45:48      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:

基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
将N分为若干个不同整数的和,有多少种不同的划分方式,例如:n = 6,{6} {1,5} {2,4} {1,2,3},共4种。由于数据较大,输出Mod 10^9 + 7的结果即可。
 
Input
输入1个数N(1 <= N <= 50000)。
Output
输出划分的数量Mod 10^9 + 7。
Input示例
6
Output示例
4

分析:这题关键在于不同的整数
一个包含数字最多的划分必定是1+2+3+....+m == n
这样(m + 1) * m <= 2 * n
可以确定m是O(sqrt(n))级别的
想到这里很容易想到用dp[i][j]表示I这个数分成j的数组成的划分有多少种。
方程为:dp[i][j] = dp[i - j][j] + dp[i - j][j - 1]
前者表示将i - j划分为j个数,每个数加1就是i划分为j个数的方案了。
但是前者这样有i-j的方案+1形成i分为j个数的方案是不完全的,因为没有1
后者则补充了这部分的答案,表示i-j划分为j个数,每个数+1,并且方案再加入一个1这个元素。
由于数不重复,所以1的个数只能为1个。

仍然用java写这些简单的题目。

技术分享
 1 package p1201;
 2 
 3 import java.util.*;
 4 import java.io.*;
 5 
 6 public class Main
 7 {
 8 
 9     /**
10      * @param args
11      */
12     final static int MOD = (int) 1e9 + 7;
13     public static void main(String[] args)
14     {
15         // TODO Auto-generated method stub
16         Scanner reader = new Scanner(System.in);
17         PrintWriter writer = new PrintWriter(System.out);
18         
19         int n = reader.nextInt();
20         int m = 0;
21         while((1 + m) * m / 2 < n) m++;
22         
23         int [][] dp = new int[n + 1][m + 1];
24         dp[0][0] = 1;
25         for(int i = 1; i <= m; i++)
26             for(int j = (1 + i) * i / 2; j <= n; j++)
27             {
28                 dp[j][i] = (dp[j - i][i] + dp[j - i][i - 1]) % MOD;
29             }
30         
31         int ans = 0;
32         for(int i = 1; i <= m; i++)
33             ans = (ans + dp[n][i]) % MOD;
34         writer.println(ans);
35         
36         reader.close();
37         writer.flush();
38     }
39 
40 }
View Code

 



51nod p1201 整数划分

标签:

原文地址:http://www.cnblogs.com/StupidBoy/p/5251726.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!