整数划分问题

整数划分是一个经典的问题。

Input

每组输入是两个整数n和k。(1 <= n <= 50, 1 <= k <= n)

Output

对于每组输入,请输出六行。

             第一行: 将n划分成若干正整数之和的划分数。

             第二行: 将n划分成k个正整数之和的划分数。 

             第三行: 将n划分成最大数不超过k的划分数。

             第四行: 将n划分成若干奇正整数之和的划分数。

             第五行: 将n划分成若干不同整数之和的划分数。

             第六行: 打印一个空行。



( 南开nodgd):全是递推题

I: f[i][j]表示i的划分为不超过j个数的划分数,此时分为两种情况: 包括i f[i-j][j]或者不包括i f[i][j-1]  
II: 初始化:i==1 或者j==1 时f[i][j]=1;



第一个f[i][j]表示i的划分为不超过j个数的划分数,f[i][j]=f[i-j][j]+f[i][j-1],最终输出f[N][N]。因为这个子问题元素可以多次使用所以递推的时候要用f[i-j][j]这个状态而不能用f[i-j][j-1]。写代码的时候外层循环j由小到大,内层循环i由小到大。

for(j=1;j<=N;j++)
f[0][j]=1;
for(j=1;j<=N;j++)
for(i=j;i<=N;i++)
f[i][j]=f[i-j][j]+f[i][j-1];
一维数组优化:
f[0]=1;
for(j=1;j<=N;j++)
for(i=j;i<=N;i++)//这个顺序每一个数可以取x次
f[i]+=f[i-j];




第二个f[i][j][k]表示把i划分成不超过j的k个数的划分数,f[i][j][k]=f[i-j][j][k-1]+f[i][j-1][k],输出f[N][N][K]。这个问题也是可以重复元素的,(如果不允许重复元素就用f[i][j][k]=f[i-j]
[j-1][k-1]+f[i][j-1][k])。写代码外层k由小到大,中层j由小到大,内层i由小到大。
for(j=0;j<=N;j++)
f[0][j][0]=1;
for(k=1;k<=K;k++)
for(j=1;j<=N;j++)
for(i=j;i<=N;i++)
f[i][j][k]=f[i-j][j][k-1]+f[i][j-1][k];


第三个递推同第一个,输出f[N][K]。



第四个f[i][j]表示把i划分成不超过j的奇数的划分数,f[i][j]=f[i-j][j]+f[i][j-2],递推循环时保证j是奇数,本质上和第一个相同。如果N是奇数输出f[N][N],N是偶数输出f[N][N-1]。(如果不允许重复元素就f[i][j]=f[i-j][j-2]+f[i][j-2]),外层循环j由小到大,内层i由小到大。
for(j=1;j<=N;j+=2)
f[0][j]=1;
for(j=1;j<=N;j+=2)
for(i=j;i<=N;i++)
f[i][j]=f[i-j][j]+f[i][j-2];

一维数组优化:

f[0]=1;
for(j=1;j<=N;j+=2)
for(i=1;i<=N;i++)
f[i]+=f[i-j];
第五个f[i][j]表示把i划分为不超过j的不同数的划分数,f[i][j]=f[i-j][j-1]+f[i][j-1]。外层循环j由小到大,内层i由小到大。显然对于每个i的分解,每个j都只被用了一次。

for(j=1;j<=N;j++)
f[0][j]=1;
for(j=1;j<=N;j++)
for(i=j;i<=N;i++)
f[i][j]=f[i-j][j-1]+f[i][j-1];

一维数组优化:

f[0]=1;
for(j=1;j<=N;j++)
for(i=N;i>=j;i--)//这个顺序代表j只能用一次,区分第一个
f[i]+=f[i-j];

注意:

(1)这些实际上都是简单的背包问题的变种,递推方法与背包问题类似。

(2)由于答案可能很大,可能涉及到高精度,但这不影响算法。

(3)以上递推都是最浅显易懂的写法,事实上除第二个以外都可以优化到用一维数组递推(省略[j]),而第二个可以优化到用二维数组递推(省略[k])



如果还有不能理解的可以草稿纸上写一下或者用程序把递推出的矩阵打出来看一下,应该就能明白了。



大概是:整数划分||DP||母函数||递推的更多相关文章

  1. [AHOI2009]中国象棋 DP,递推,组合数

    DP,递推,组合数 其实相当于就是一个递推推式子,然后要用到一点组合数的知识 一道很妙的题,因为不能互相攻击,所以任意行列不能有超过两个炮 首先令f[i][j][k]代表前i行,有j列为一个炮,有k列 ...

  2. 2014北大研究生推免机试(校内)-复杂的整数划分(DP进阶)

    这是一道典型的整数划分题目,适合正在研究动态规划的同学练练手,但是和上一个随笔一样,我是在Coursera中评测通过的,没有找到适合的OJ有这一道题(找到的ACMer拜托告诉一声~),这道题考察得较全 ...

  3. HDU 5965 三维dp 或 递推

    题意:= =中文题 思路一:比赛时队友想的...然后我赛后想了一下想了个2维dp,但是在转移的时候,貌似出了点小问题...吧?然后就按照队友的思路又写了一遍. 定义dp[i][j][k],表示第i列, ...

  4. 51nod 1201 整数划分 dp

    1201 整数划分 基准时间限制:1 秒 空间限制:131072 KB   收藏  关注 将N分为若干个不同整数的和,有多少种不同的划分方式,例如:n = 6,{6} {1,5} {2,4} {1,2 ...

  5. 【BZOJ4944】【NOI2017】泳池 概率DP 常系数线性递推 特征多项式 多项式取模

    题目大意 有一个\(1001\times n\)的的网格,每个格子有\(q\)的概率是安全的,\(1-q\)的概率是危险的. 定义一个矩形是合法的当且仅当: 这个矩形中每个格子都是安全的 必须紧贴网格 ...

  6. [NOI2017]泳池——概率DP+线性递推

    [NOI2017]泳池 实在没有思路啊~~~ luogu题解 1.差分,转化成至多k的概率减去至多k-1的概率.这样就不用记录“有没有出现k”这个信息了 2.n是1e9,感觉要递推然后利用数列的加速技 ...

  7. bzoj 3612 [Heoi2014]平衡——整数划分(dp)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3612 因为力矩的缘故,变成了整数划分. 学习到了整数划分.就是那个图一样的套路.https: ...

  8. codeforces 696C PLEASE 概率dp+公式递推+费马小定理

    题意:有3个杯子,排放一行,刚开始钥匙在中间的杯子,每次操作,将左右两边任意一个杯子进行交换,问n次操作后钥匙在中间杯子的概率 分析:考虑动态规划做法,dp[i]代表i次操作后的,钥匙在中间的概率,由 ...

  9. hdu5092 dp(递推)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5092 题意:给一个m*n的矩阵,找到一个纵向的"线"使得线上的和最小并 ...

随机推荐

  1. hive中拉链表

    在有些情况下,为了保持历史的一些状态,需要用拉链表来做,这样做目的在可以保留所有状态的情况下可以节省空间. 拉链表适用于以下几种情况吧 数据量有点大,表中某些字段有变化,但是呢变化的频率也不是很高,业 ...

  2. SQL入门经典(四)之创建和修改数据表

    本章主要讲如何使用脚本创建数据库:如何使用脚本创建表:如何删除对象和修改对象. CREATE 语句:CREATE <object type> <onject name> 创建数 ...

  3. Scau 8633 回文划分 mancher + dp

    时间限制:1000MS 内存限制:1000K 提交次数: 通过次数: 题型: 编程题 语言: G++;GCC Description 我们说一个字符串是回文串,那么意味着这个串从两边读起来的字母都是一 ...

  4. 第9章 使用ssh服务管理远程主机。

    章节简述: 学习使用nmtui命令配置网卡参数.手工将多块网卡做绑定.使用nmcli命令查看网卡信息和使用ss命令查看网络及端口状态. 完整演示sshd服务配置方法并详细讲述每个参数的作用,实战基于密 ...

  5. js——事件

    焦点:使浏览器能够区分用户输入的对象,当一个元素有焦点的时候,那么他就可以接收用户的输入. 我们可以通过一些方式给元素设置焦点 1.点击 2.tab 3.js 不是所有元素都能够接收焦点的.能够响应用 ...

  6. bootstrap table编辑操作的时候 在模态框里加载iframe页面(加载的页面是在另一个页面做编辑)的时候如何关闭模态框和刷新table

    //关闭模态框                             window.parent.$('#myModal').modal('hide'); //修改成功后刷新table表格      ...

  7. applicationContext.xml 模板

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  8. kivy中bind的使用

    一般在kivy中使用bind()来绑定回调函数,所谓回调函数,个人理解就是一个预先定义好的方法, 因为APP是静态的, 需要等待用户进行操作, 特定的操作背后都绑定了特定的回调函数, 一般有两种类型: ...

  9. Python_getter和setter方法

    当给属性赋值的时候,使用实例.属性=属性值的方式显然把属性暴露出来了,并且也无法对属性值进行限制检查,java中提供了setter和getter方法,那么python是如何做的呢?更多内容请参考:Py ...

  10. python 插值查找

    def binary_search(lis, key): low = 0 high = len(lis) - 1 time = 0 while low < high: time += 1 # m ...