一,问题描述

给定若干个字符,求解 这些字符能够表示的最多组合个数。比如{'a','b','c'} 一共有七种组合。(每种组合没有重复的字符 且 组合的种数与顺序无关,如 ab 和 ba 是同一种组合)

a、b 、c 、ab 、ac 、bc 、abc

其实,求组合个数,可以用公式来求解:具给定 n种字符,一共有  c(n,1)+c(n,2)+...+c(n,n)种不同的组合。其中,c(n,i)表示:从n个字符中任选 i 个的组合数,数学表示为:C in

二,DP算法思路

既然已经可以用上面的公式 c(n,1)+c(n,2)+...+c(n,n) 来计算不同的组合数了,那为什么还用DP?因为,上面的公式只能给定组合数,但是不能给出具体是哪些组合。

假设输入 m 个字符(互不相同),则这些字符只能构成长度为 1,2,....m 的组合,设某个组合的长度为 n。即: 1 =< n <= m

设 c[m][n] 表示 使用 m 种不同的字符,表示长度最多为 n 的组合个数 的最大值

最大值 体现了最优子问题性质。最优子问题分析如下:把字符组合分成两部分,第一个字符 以及剩下的所有字符。

对于第 m 种字符而言,只有两种情况:①是字符组合的第一个字符,②不是在字符组合的第一个字符。因此,可以应用《组合数学》中的加法原理。(比如 'abc' 就是一个字符组合)

c[m][n]=c[m-1][n-1] + c[m-1][n]

c[m-1][n-1],表示第 m 个字符字符组合中的第一个字符。此时,该问题变成:用 1,2,...m-1个字符(共 m-1 种) 来 组合 长度为 n-1的 字符组合(‘字符串’)

c[m-1][n],表示第 m 个字符不是 字符组合中的第一个字符。此时,该问题变成:在剩余的 m-1种字符里面选出 n 个字符来组合。???(有点不太对)

'm' ? ? .... ?             第一个字符是 'm'

'*'  ? ? .....?             第一个字符不是 'm'

注意,原问题表示的字符组合 长度是 n

这个问题的DP求解与 动态规划求解最多有几种方案求解硬币找零问题 非常相似。

同时,这也是一个典型的加法原理的应用。

三,代码实现

public class AllComposite {/*** * @param str 存储可用的字符种类* @param m 可用的字符种类数* @param n 组合中的最大长度* @return  */public static int allCombination(char[] str, int m, int n){//base conditionif(m == 0 && n > 0)return 1;if(n == 0)return 0;return allCombination(str, m-1, n-1)+ allCombination(str, m-1, n);}public static int dpAllCombination(char[] str, int n){int[][] c = new int[n+1][n+1];//可根据上面的递归来判断初始条件for(int i = 0; i <=n; i++){c[0][i] = 1;c[i][0] = 0;//c[0][0]=0
        }//c[n][n]=c[n-1][m-1] + c[n-1][m]for(int i = 1; i <=n; i++){for(int j = 1; j <=n; j++){c[i][j] = c[i-1][j-1] + c[i-1][j];}}return c[n][n];}public static void main(String[] args) {char[] str = {'a','b','c','d'};int m ,n ;m = n = str.length;int result = allCombination(str, m, n);int result2 = dpAllCombination(str, n);System.out.println(result);System.out.println(result2);}
}

对于初始条件的确定,可以先画一个小的示例图来确定。比如:allCombination({'a','b','c'}, 3)......

在代码里面 记录下具体选了哪些字符,就可以打印输出具有的字符组合了。其实我也不会。

时间复杂度分析:从上面的递归方法来看:递归表达式为 T(m)=2T(m-1),得出:T(m)=2^m ,指数级复杂度

而从上面的动态规划求解方法来看:时间复杂度为O(m^2)

原因就是:这个问题存在重叠的子问题,对于DP而言,不需要重复地计算某些值,而是通过查找求得。这篇文章 求解两个字符串的最长公共子序列 详细分析了DP的优势在哪里。

(动态规划的两个基本特征:①最优子结构;②重叠子问题)

四,参考资料

http://www.cnblogs.com/hapjin/p/5579737.html

求解两个字符串的最长公共子序列

http://wuchong.me/blog/2014/07/28/permutation-and-combination-realize/

动态规划求解所有字符的组合数相关推荐

  1. python实现动态规划求解给定矩阵的和最大的子数组(矩阵中数字正负均存在)

    本篇博文比较简单没有太多实际意义,只是为了练习一下,动态规划我并不熟悉,也是刚处于学习的阶段. 问题: 给定一个指定的矩阵,维数小于1000,在矩阵的所有子数组中寻找具有最大和的子数组求和输出. 思路 ...

  2. 1008-----算法笔记----------0-1背包问题(动态规划求解)

    1.问题描述 给定n种物品和一个背包,物品i的重量是wi,其价值为vi,背包的容量为C.问:应该如何选择装入背包的物品,使得装入背包中物品的总价值最大? 2.问题分析 上述问题可以抽象为一个整数规划问 ...

  3. 动态规划之KMP字符匹配算法

    动态规划之KMP字符匹配算法 文章目录 动态规划之KMP字符匹配算法 一.问题引入 二. KMP 算法概述 三. 状态机概述 四. 构建状态转移图 五. 代码实现 六. 最后总结 本文的KMP算法是通 ...

  4. 子串、子数组与子序列类型问题的动态规划求解(Leetcode题解-Python语言)

    一般来说,子串和子数组都是连续的,而子序列是可以不连续的,遇到子序列问题基本上都是用动态规划求解. 53. 最大子数组和(剑指 Offer 42. 连续子数组的最大和) class Solution: ...

  5. python用动态规划求删除路径_Python | 动态规划求解TSP

    解题思路主要有两部分: i为当前节点(城市),S为还没有遍历的节点(城市集合),表示从第i个节点起,经历S集合中所有的点,到达终点的最短路径长度. 回溯找到最优的路径,需要将S集合一一对应一个数字(类 ...

  6. 使用动态规划求解算法问题的五大特点总结(附基于Python的参考代码)

    什么样的问题应使用动态规划求解 前言 一.求"最"优解问题(最大值和最小值) 1. 乘积最大子数组 问题描述 示例 题目分析 参考代码 2. 最长回文子串 问题描述 示例 题目分析 ...

  7. 01背包问题 动态规划求解方法 动态方程的详细解释 能理解的解释(附python代码)

    01背包问题属于组合优化问题:假设你要出门旅游,你现在有一个书包,这个书包的容量(capacity)有限,有很多物品如牙刷.防晒霜.雨伞.水杯等等,但书包装不下所有物品,因此我们必须有所取舍.那么通常 ...

  8. 动态规划求解多段图问题

    动态规划求解多段图问题(非递归) 问题描述 求解思路 动态规划逆序解法 逆序实现代码 动态规划逆序解法 顺序实现代码 问题描述 如图所示,在A处有一水库,现需要从A点铺设一条管道到E点,边上的数字表示 ...

  9. 数据结构和算法——用动态规划求解最短路径问题

    一.动态规划求解问题的思路     在<算法导论>上,动态规划的求解过程主要分为如下的四步: 描述最优解的结构 递归定义最优解的值 按自底向上的方式计算最优解的值 由计算出的结果构造一个最 ...

最新文章

  1. Centos安装tomcat,haproxy,jdk
  2. poj 3349 雪花
  3. dcc garch matlab,如何用Eviews或者MATLAB实现DCC-garch模型?
  4. 阿尔法贝塔阀原理_图总结 - 阿尔法个贝塔 - 博客园
  5. linux tar 使用
  6. TypeError: cannot convert the series to <class ‘float‘>问题解决
  7. win10你的组织已关闭自动更新问题怎么解决?
  8. 新年到!充满年味的海报给你参考
  9. android studio maven gradle,Maven Dependencies with Android Studio / Gradle
  10. es6的初级简易总结
  11. JAVA设计模式之工厂模式(简单,工厂,抽象)
  12. VS2015安装使用番茄助手Visual Assist
  13. 常用的Wi-Fi产品调试测试工具
  14. WordPress主题制作全过程(一):基础准备
  15. linux基础--认识文件以及vi编辑器
  16. 求最小公倍数利用数组java_菜鸟级求解:Java求1到20的最小公倍数
  17. ❥关于C++之写入/读取文本文件
  18. 批量更新mysql数据(万条数据秒完成)
  19. Java工程师培训课(十一、新的开始)
  20. Beta冲刺-星期四

热门文章

  1. python创建和控制的实体称为_Python eds包_程序模块 - PyPI - Python中文网
  2. 报错, nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException
  3. Python程序:求最小公倍数
  4. bzoj4819 [Sdoi2017]新生舞会 分数规划(实数二分)+网络流检验
  5. 2017.7.19 Race 思考记录
  6. 自创算法——暴力自动机
  7. 【英语学习】【Daily English】U13 Holiday L03 I certainly didn't expect this
  8. tracepro杂散光分析例子_AES分析中的干扰效应及校正,你知道吗?
  9. jedis-2.4.1 中的JedisPoolConfig没MaxActive属性
  10. 通过MFC窗口获取方向键