题意:问把整数N分成K份的分法数。(与“放苹果”不同,在这题不可以有一份为空,但可以类比)
解法:f[i][j]表示把i分成j份的方案数。
f[i][j]=f[i-1][j-1](新开一份,放1)
而i≥j时,f[i][j]=f[i-1][j-1]  +f[i-j][j](不新开一份时的方案数与每份中都少放1的方案数相同)

一种更好的解释——方法可以分为两类:
 1. n 份中不包含 1 的分法,为保证每份都 >= 2,可以先拿出 k 个 1 分。到每一份,然后再把剩下的 n- k 分成 k 份即可,分法有: dp[n-k][k]
 
2. n 份中至少有一份为 1 的分法,可以先那出一个 1 作为单独的1份,剩下的 n- 1 再分成 k- 1 份即可,分法有:dp[n-1][k-1]

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std; int f[210][10];
int main()
{
int n,k;
scanf("%d%d",&n,&k);
memset(f,0,sizeof(f));
for (int i=1;i<=n;i++) f[i][1]=1;
for (int i=1;i<=n;i++)
for (int j=2;j<=k;j++)
if (j<=i)
f[i][j]=f[i-1][j-1]+f[i-j][j];
printf("%d",f[n][k]);
return 0;
}

附——整数划分的解题方法

{Article 1 转自——http://blog.csdn.net/luke2834/article/details/49429353 ;                                                   Article 2 转自——http://blog.csdn.net/athenaer/article/details/8265234}

其中一些问题具体实现见我另外几篇博文——http://www.cnblogs.com/konjak/p/6004018.html & http://www.cnblogs.com/konjak/p/6004636.html

我略修改了一下原博文,大家可比较一下。Article 1的方法很特别,Article 2的思路常规但也挺重要的。

问题描述:给定一个正整数N和K

1.
将n划分成若干正整数之和的划分数。

2.将n划分成k个正整数之和的划分数。

3.将n划分成最大数不超过k的划分数。

4.将n划分成若干奇正整数之和的划分数。

5.将n划分成若干不同整数之和的划分数。

Article 1:总的来说这些都是背包问题;

第一个问,就是一个完全背包,背包有 1 --- N 种,第 i 种背包的重量为 i ,价值为 i ;这很好解决:

1 dp[0] = 1;
2 for (i = 1;i <= N;i++)
3 for (j = i;j <= N;j++)
4 dp[j] += dp[j-i];

其中 dp[j] 是用前 i 个数能构成 j 的种类数,则结果就为 dp[N]

看完这个问题了,那么 第3个问就知道了 , 即用前 K 种背包来装 所得结果,只需把第一层循环的 i <= N 改为 i <= K 即可;

1 dp[0] = 1;
2 for (i = 1;i <= K;i++)
3 for (j = i;j <= N;j++)
4 p[j] += dp[j-i];

那么第四个问呢,想想是奇数,那么 i = 2,4,6,…… 等等值就不能取了,因为这些背包种类不合要求,这很简单啊  i++ 改为 i += 2 不就行了;

1 dp[0] = 1;
2 for (i = 1;i <= N;i+=2)
3 for (j = i;j <= N;j++)
4 dp[j] += dp[j-i];

再看看第五个问,若干个不同的???想到了什么,就是一种背包最多只能用一次???这是什么,经典的 01背包 啊,与第一个问的不同就是第二层循环的顺序而已;

1 dp[0] = 1;
2 for (i = 1;i <= N;i++)
3 for (j = n;j >= i ;j--)
4 dp[j] += dp[j-i];

最后我们来思考第二个问:要求只要 K 个,这怎么办呢???想想特殊情况…… 如果 K = 1 呢,只能是 N 咯,若果 N = 0 呢, 结果只能是 0 种可能啊,那同样N < K 的话,不可能分啊。结果为 0 ,好,特殊的考虑完了,那么我们再考虑,分的结果中有没有 1 。 如果有1,那么就把剩下的 N - 1 分成 K - 1 份 ; 如果没有呢,那么我们先拿出 K 份 给每一堆 一个1, 再把剩下的 N - K 分成 K 份就行了。

Article 2:整数划分 --- 一个老生长谈的问题:

1.将n划分成不大于m的划分法: P.S.依问题定义——不定义划分成多少份。

  1).若是划分多个整数可以存在相同的:

   dp[n][m]= dp[n][m-1]+ dp[n-m][m]  dp[n][m]表示整数 n 的划分中,每个数不大于 m 的划分数。

      分两种情况:

       a.划分中每个数都小于 m,相当于每个数不大于 m- 1, 故划分数为 dp[n][m-1].

       b.划分中有一个数为 m. 那就在 n中减去 m ,剩下的就相当于把 n-m 进行划分, 故划分数为 dp[n-m][m];

  2).若是划分多个不同的整数:

  dp[n][m]= dp[n][m-1]+ dp[n-m][m-1]   dp[n][m]表示整数 n 的划分中,每个数不大于 m 的划分数。

    分两种情况:

      a.划分中每个数都小于m,相当于每个数不大于 m-1,划分数为 dp[n][m-1].

      b.划分中有一个数为 m.在n中减去m,剩下相当对n-m进行划分,

   并且每一个数不大于m-1,故划分数为 dp[n-m][m-1]

2.将n划分成k个数的划分法:

        dp[n][k]= dp[n-k][k]+ dp[n-1][k-1];

  方法可以分为两类:

     第一类: n 份中不包含 1 的分法,为保证每份都 >= 2,可以先拿出 k 个 1 分。到每一份,然后再把剩下的 n- k 分成 k 份即可,分法有: dp[n-k][k]

     第二类: n 份中至少有一份为 1 的分法,可以先那出一个 1 作为单独的1份,剩下的 n- 1 再分成 k- 1 份即可,分法有:dp[n-1][k-1]

3.将n划分成若干奇数的划分法:

g[i][j]:将i划分为j个偶数;f[i][j]:将i划分为j个奇数
     g[i][j] = f[i - j][j];f[i][j] = f[i - 1][j - 1] + g[i - j][j];
         方法可以分为两类:
       第一类:i中拿出j个1分到每一份中,将剩余的i-j分成j个奇数
       第二类:一份包含奇数1,剩余的i-1分成j-1个奇数;另一种,每份至少大于1,将j个1拿出来分到每一份中,其余i-j分成j份

【noi 2.6_8787】数的划分(DP){附【转】整数划分的解题方法}的更多相关文章

  1. HDU4632 Poj2955 括号匹配 整数划分 P1880 [NOI1995]石子合并 区间DP总结

    题意:给定一个字符串 输出回文子序列的个数    一个字符也算一个回文 很明显的区间dp  就是要往区间小的压缩! #include<bits/stdc++.h> using namesp ...

  2. CodeForces 768E SG函数 整数划分 Game of Stones

    一个标准的NIM游戏 加上一条规则:每堆石子对于每个数目的石子只能被取一次 可以SG打表 dp[i][j]表示现在有i个石子 j是可以取的石子数的状压 第i位为1就表示i个石子没被取过 #includ ...

  3. NOI.AC 31 MST——整数划分相关的图论(生成树、哈希)

    题目:http://noi.ac/problem/31 模拟 kruscal 的建最小生成树的过程,我们应该把树边一条一条加进去:在加下一条之前先把权值在这一条到下一条的之间的那些边都连上.连的时候要 ...

  4. 51nod 1201 整数划分 基础DP

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

  5. NYOJ90 整数划分(经典递归和dp)

    整数划分 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 将正整数n表示成一系列正整数之和:n=n1+n2+…+nk,  其中n1≥n2≥…≥nk≥1,k≥1.  正 ...

  6. HDU 1028 Ignatius and the Princess III dp整数划分

    http://acm.hdu.edu.cn/showproblem.php?pid=1028 dp[i][j]表示数值为i,然后最小拆分的那个数是j的时候的总和. 1 = 1 2 = 1 + 1 . ...

  7. bzoj 3612: [Heoi2014]平衡【整数划分dp】

    其实就是-n~n中求选k个不同的数,和为0的方案数 学到了新姿势叫整数划分,具体实现是dp 详见:https://blog.csdn.net/Vmurder/article/details/42551 ...

  8. 【NOI2019模拟2019.6.27】B (生成函数+整数划分dp|多项式exp)

    Description: \(1<=n,k<=1e5,mod~1e9+7\) 题解: 考虑最经典的排列dp,每次插入第\(i\)大的数,那么可以增加的逆序对个数是\(0-i-1\). 不难 ...

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

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

随机推荐

  1. 剑指offer 查找和排序的基本操作:查找排序算法大集合

    重点 查找算法着重掌握:顺序查找.二分查找.哈希表查找.二叉排序树查找. 排序算法着重掌握:冒泡排序.插入排序.归并排序.快速排序. 顺序查找 算法说明 顺序查找适合于存储结构为顺序存储或链接存储的线 ...

  2. 网络之HTTPS

    文章目录 HTTPS的基本概念 HTTP和HTTPS的区别 HTTPS的优点 对称加密和非对称加密 对称加密 非对称加密 HTTPS采用的加密方式 认证 证书的组成 使用openssl怎么制造证书 H ...

  3. spring ioc踏出第一步

    spring IOC(容器) AOP(面向切面编程) IOC容器:他的功能就是可以整合像 Structs2 .Hibernate.Mybatis: IOC:控制反转:所谓的控制就是控制资源的获取方法, ...

  4. C语言指针-从底层原理到花式技巧,用图文和代码帮你讲解透彻

    这是道哥的第014篇原创 目录 一.前言 二.变量与指针的本质 1. 内存地址 2. 32位与64位系统 3. 变量 4. 指针变量 5. 操作指针变量 5.1 指针变量自身的值 5.2 获取指针变量 ...

  5. 【Linux】md5sum 生产所有文件的md5值,并对照目标文件是否相同

    现在加入有很多很多文件需要测试md5,想看下是否都传输成功了,如何批量生成文件的md5并且逐条对照呢? 下面来简单介绍下 md5sum这个命令有一个选项"-c" 这个选项的意思是c ...

  6. 【Linux】快速创建文件的命令方法

    [root@centos7 dir1]# ll total 0 -rw-r--r-- 1 root root 0 Aug 15 02:39 file1 -rw-r--r-- 1 root root 0 ...

  7. VSCode运行时弹出powershell

    问题 安装好了vscode并且装上code runner插件后,运行代码时总是弹出powershell,而不是在vscode底部终端 显示运行结果. 解决方法 打开系统cmd ,在窗口顶部条右击打开属 ...

  8. 什么是xss攻击

    概述: XSS攻击是Web攻击中最常见的攻击方法之一,它是通过对网页注入可执行代码且成功地被浏览器 执行,达到攻击的目的,形成了一次有效XSS攻击,一旦攻击成功,它可以获取用户的联系人列 表,然后向联 ...

  9. SQL Server management studio使用sa连接时报错与伺服器的连接已成功,但在登入程序是发生错误

    使用Sql Server management studio的sa用户连接数据库时,报如下错误 解决方法: 1.使用windows验证登录 2.右键点击连接,点击属性,点击安全性,选择混合验证 3.重 ...

  10. Hadoop2.7.7阿里云安装部署

    阿里云的网络环境不需要我们配置,如果是在自己电脑上的虚拟机,虚拟机的安装步骤可以百度.这里是单机版的安装(也有集群模式的介绍)使用Xshell连接阿里云主机,用命令将自己下载好的安装包上传到服务器 # ...