整数的划分

 整数的分划问题。  如,对于正整数n=6,可以分划为:  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+1  现在的问题是,对于给定的正整数n,编写算法打印所有划分。 用户从键盘输入 n (范围1~10) 程序输出该整数的所有划分。

这个题目我用的递归,但是思路和我网上看到的不一样,貌似更简单一点,

/**
* 5=1+1+1+1+1      4=1+1+1+1    3=1+1+1      2=1+1       1=1
* 5=1+1+1+2      4=1+1+2     3=1+2        2=2
* 5=1+1+3          4=1+3         3=3
* 5=1+2+2          4=2+2
* 5=1+4          4=4
* 5=2+3
* 5=5
*/

//观察以上整数划分,n+1的划分包括n的所有划分+1,n+1=n+1,和不带1的所有划分三部分,

//其中第三部分,可以从是第一部分中求得,首先划分的数字都从小到大排列,如上所示,

//如果一个划分的元素个数大于2,且前两个元素之和小于等于第三个个数,

//那么合并这个划分的前两个数,其他的不变,从而生成新的划分

代码如下:

public static Map getlist(int n){
  Map<String,String> map = new HashMap<String,String>();
  if(n==1){
    map.put("1", "1=");
    return map;
  }
  map = getlist(n-1);
  Map<String, String> map2 = new HashMap();
  for (Map.Entry entry : map.entrySet()) {
    String key = (String) entry.getKey( );
    String value = (String) entry.getValue( );
    String str =iscreate("1+"+key);
    if(str!=null){
      map2.put(str, String.valueOf(Integer.valueOf(value.replace("=", ""))+1)+"=");
    }
    map2.put("1+"+key, String.valueOf(Integer.valueOf(value.replace("=", ""))+1)+"=");
  }
  map2.put(""+n, n+"=");
  return map2;

}
public static String iscreate(String s){
  String[]str=s.trim().split("\\+");
  if(str.length>=3&&(Integer.valueOf(str[0])+Integer.valueOf(str[1])<=Integer.valueOf(str[2]))){
    return String.valueOf(Integer.valueOf(str[0])+Integer.valueOf(str[1]))+s.substring(3);
  }
  return null;
}

public static void main(String[]args){

  System.out.println("请输入要划分的整数:");
  Scanner s = new Scanner(System.in);

  int n=System.nextInt();
  Map<String,String> map = getlist(7);
  TreeMap<String,String> treemap = new TreeMap<String,String>(map);
  for (Map.Entry entry : treemap.entrySet()) {
    String key = (String) entry.getKey( );
    String value = (String) entry.getValue( );
    System.out.println(value+key);
  }

}

结果如下:

请输入要划分的整数:

7

7=1+1+1+1+1+1+1
7=1+1+1+1+1+2
7=1+1+1+1+3
7=1+1+1+2+2
7=1+1+1+4
7=1+1+2+3
7=1+1+5
7=1+2+2+2
7=1+2+4
7=1+3+3
7=1+6
7=2+2+3
7=2+5
7=3+4
7=7

新人,代码写的不好,见谅!

整数的划分,布布扣,bubuko.com

时间: 2024-11-05 19:41:52

整数的划分的相关文章

递归与分治_整数的划分

#include <iostream> #include <cstdio> using namespace std; /* * 求整数n的划分 * n, m * 在整数n的所有划分中, 最大加数 n1<=m 的划分记做p(n, m); * 1. p(n, 1) = 1; (m == 1) * 2. p(n, n) = 1 + p(n, n-1); (n == m) * 3. p(1, m) = 1; (n == 1) * 4. p(n, m) = p(n, m-1) + p(

【例题2-5】整数的划分

3 = 1 + 1 +1 3 = 2 + 1 3 = 3 则q(n,m)表示n的划分中最大值不超过m的方案书,q(3,3)=3. [题解] q(n,m)=q(n-m,m)+q(n,m-1);//放一个m在开头+不放m在开头然后尝试<=m-1 q(0,m)=1; ① n<0 || m<=0 ->f(n,m)=0 ② ①在②前. [代码] #include <cstdio> #define ll long long using namespace std; //计算n的划分

HDU acm1028 整数划分 递归问题(递推)

我们用递归+记忆化的方法来解决普通整数划分问题:定义 f(n,m)为将整数n划分为一系列整数之和,其中加数 最大不超过m. 得到下面的递推关系式: 当n==1 || m==1 只有一种划分,即 1 或者 1+1+1......+1 当m>n 显然,等价于 f(n,n) 当m==n 此时:我考虑加数包含m与否的两种情况: 1)划分不包含m,即f(n,m-1)---所有m-1的划分 2)划分包含 m,此时只有一种即 m 所以当m==n时,有 f(n,m)=f(n,m-1)+1 当m<n时, 1)包

HDU 1028 整数划分问题 DP

http://acm.hdu.edu.cn/showproblem.php?pid=1028 将一个正整数n划分成多个正整数的和,例如4可以划分为4,1 + 3,2 + 2,1 + 1 + 2, 1 + 1 + 1(1 + 3和3 + 1算作一种划分). 在网上找到了两种做法 方法1: dp[i][j] 的含义是将一个正整数i划分为j个整数的和有几种分法.转移方程很好写但是不太好想. 将此划分分为两种情况,划分中包括1和不包括1.若划分中包括1,则只需将剩余的整数i - 1划分成j - 1个整数

整数划分问题(仅仅显示种类数)

这边博客对于整数划分问题,仅仅要求求出对于每个整数可以划分的种类数,採用金典的递归的办法解决. #include<iostream> using namespace std; /* *整数划分问题(仅仅显示种类数) */ int GetIntDivision(int n,int m) { if(n==1&&m>=1) return 1; if(n>=1&&m==1) return 1; if(m>n) return GetIntDivision

hdu1028 划分数

题意是将一个整数N划分成不超过N个整数的和, 我们定义d[i][j]为j划分成不超过i个整数的和的方案数, 那么d[i][j] = d[i][j-i](全大于0) + d[i-1][j](不全大于0). 答案就是d[N][N], 代码如下: #include <iostream> #include <algorithm> using namespace std; typedef long long LL; LL d[150][150]; int main() { d[0][0] =

VB.NET 内存指针和非托管内存的应用

介绍 Visual Basic 从来不像在C或C++里一样灵活的操纵指针和原始内存.然而利用.NET框架中的structures 和 classes,可以做许多类似的事情.它们包括 IntPtr,   Marshal 以及 GCHandle. 这些structures(结构) 和classes(类) 允许你在托管和非托管环境中进行交互.本文中将向您展示如何使用这些structures 和 classes 去完成指针和内存的操作. 关于 IntPtr 结构 IntPtr  结构的行为像一个整型指针

java 排序算法 折半 堆 希尔 快速 整理

试题1:折半查找 折半查找是在有序表中,把待查找数据值与查找范围的中间元素值进行比较,会有三种情况出现: 1)待查找数据值与中间元素值正好相等,则放回中间元素值的索引. 2)待查找数据值比中间元素值小,则以整个查找范围的前半部分作为新的查找范围,执行1),直到找到相等的值. 3)待查找数据值比中间元素值大,则以整个查找范围的后半部分作为新的查找范围,执行1),直到找到相等的值 4)如果最后找不到相等的值,则返回不存储数据的备用单位0. 给你的问题是,标准输入一升序排列有序整数表,使用折半查找方法

快速排序模板

以某个记录(元素)为界(该记录称为支点或枢轴),将待排序列分成两部分: ①一部分: 所有记录的关键字大于等于支点记录的关键字 ②另一部分: 所有记录的关键字小于支点记录的关键字 算法描述: 1.任取待排序记录序列中的某个记录(例如取第一个记录)作为基准(枢),按照该记录的关键字大小,将整个记录序列划分为左右两个子序列 2.左侧子序列中所有记录的关键字都小于或等于基准记录的关键字 3.右侧子序列中所有记录的关键字都大于基准记录的关键字 4.基准记录则排在这两个子序列中间(这也是该记录最终应安放的位