此题是个非常经典的题目,这个题目包含了整数划分(一)和整数划分(二)的所有情形,而且还增加了其它的情形,主要是用递归或者说是递推式来解,只要找到了递推式剩下的任务就是找边界条件了,我觉得边界也是非常重要的一步,如果找不准边界,这个题也很难做出来,当时我就是找边界找了好长时间,边界得琢磨琢磨。递推步骤如下:

第一行:将n划分成若干正整数之和的划分数。
状态转移方程:dp[i][j]:和为i、最大数不超过j的拆分数
dp[i][j]可以分为两种情况:1、拆分项至少有一个j 2、拆分项一个j也没有
dp[i][j] = dp[i-j][[j] + dp[i][j-1]

第二行:将n划分成k个正整数之和的划分数。
dp[n-k][k]:相当于把k个1从n中拿出来,然后和n-k的拆分项相加的个数

第三行:将n划分成若干最大不超过k的正整数之和的划分数。
dp[n][k]

第四行:将n划分成若干奇正整数之和的划分数。
dp1[i][j]是当前的划分数为i,最大值为j时的中的划分数,则状态转移方程为
if(i < j && j % 2 == 1)
dp1[i][j] = dp1[i][i]
if(i < j && j % 2 == 0) (最大数不可能为偶数)
dp1[i][j] = dp1[i][i-1]
划分数中有j时的划分为dp[i][j - 2],因为它是奇数,所以要减2,
如果划分数中没有j的时候, 则它的数目可以写成dp1[i-j][j];意思就是i去掉j后,然后再划分最大为j的
即dp1[i][j] = dp1[i-j][j] + dp1[i][j-2]

第五行:将n划分成若干完全不同正整数之和的划分数。
dp2[i][j]可以分两种情况:1、dp1[i][j-1]为不选择j时的方案 2、dp1[i-j][j-1]为选择j时的方案
0-1背包:dp2[i][j] = dp2[i][j-1] + dp2[i-j][j-1]

方法一(递归法):

 #include <stdio.h>
 //less_m(n, m)表示将n划分为最大是m的数
 int less_m(int n, int m)
 {
      || m == )
         ;
     if(n < m)
         return less_m(n, n);
     else if(n == m)
          + less_m(n, m - );
     else
         ) + less_m(n - m, m);
 }
 //count(n, m)表示将n划分为m个数
 int count(int n, int m)
 {
     if(n < m)
         ;
      || n == m)
         ;
     else
         , m - ) + count(n - m, m);
 }
 //odd(n, m)表示将n划分为最大数为m的奇数之和
 int odd(int n, int m)
 {
     )
         ;
      && m %  == )
         ;
      && m == )
         ;
     if(n < m)
     {
          == )
             );
         else
             return odd(n, n);
     }
     else
     {
         );
     }

 }
 //not_duplicate(n, m)是将n划分为最大为m的数, 并且没有重复的
 int not_duplicate(int n, int m)
 {
     )
         ;
      || n == )
         ;
     if(n < m)
         return not_duplicate(n, n);
     else
         ) + not_duplicate(n - m, m - );
 }

 int main()
 {
     int n, k;
     while(~scanf("%d %d", &n, &k))
     {
         printf("%d\n", less_m(n, n));
         printf("%d\n", count(n, k));
         printf("%d\n", less_m(n, k));
          == )
             printf("%d\n", odd(n, n));
         else
             printf());
         printf("%d\n\n", not_duplicate(n, n));
     }

     ;
 }

方法二(递推法dp):

 #include <stdio.h>
 ;
 int dp[MAX][MAX], dp1[MAX][MAX], dp2[MAX][MAX];
 void divide()
 {
     dp[][] = ;
     ; i < MAX; i++)
     {
         ; j < MAX; j++)
         {
             if(i < j)
                 dp[i][j] = dp[i][i];
             else
                 dp[i][j] = dp[i][j - ] + dp[i - j][j];
         }
     }
 }
 //这是划分奇数的函数
 void divide1()
 {
     ; i < MAX; i++)
         dp1[i][] = ;
     ; i < MAX; i += )
         dp1[][i] = ;
     dp1[][] = ;
     ; i < MAX; i++)
     {
         ; j < MAX; j += )
         {
             if(i < j)
             {
                  == )
                     dp1[i][j] = dp1[i][i];
                 else
                     dp1[i][j] = dp1[i][i - ];
             }
             else
                 dp1[i][j] = dp1[i][j - ] + dp1[i - j][j];
         }
     }
 }
 //划分没有重复数字的函数
 void divide2()
 {
     ; i < MAX; i++)
         dp2[][i] = dp2[][i] = ;
     ; i < MAX; i++)
     {
         ; j < MAX; j++)
         {
             if(i < j)
                 dp2[i][j] = dp2[i][i];
             else
                 dp2[i][j] = dp2[i][j - ] + dp2[i - j][j - ];
         }
     }
 }

 int main()
 {
     int n, k;
     divide();
     divide1();
     divide2();
     while(~scanf("%d %d", &n, &k))
     {
         printf("%d\n", dp[n][n]);
         printf("%d\n", dp[n - k][k]);
         printf("%d\n", dp[n][k]);
         //先要判断要划分的数是否是奇数
         printf() ? dp1[n][n] : dp1[n][n - ]);
         printf("%d\n\n", dp2[n][n]);
     }

 }

NYOJ-571 整数划分(三)的更多相关文章

  1. nyoj 90 整数划分

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

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

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

  3. 整数划分 Integer Partition(二)

    本文是整数划分的第二节,主要介绍整数划分的一些性质. 一 先来弥补一下上一篇文章的遗留问题:要求我们所取的 (n=m1+m2+...+mi )中  m1 m2 ... mi连续,比如5=1+4就不符合 ...

  4. 整数划分 Integer Partition(一)

    话说今天百度面试,可能是由于我表现的不太好,面试官显得有点不耐烦,说话的语气也很具有嘲讽的意思,搞得我有点不爽.Whatever,面试中有问到整数划分问题,回答这个问题过程中被面试官搞的不胜其烦,最后 ...

  5. 大概是:整数划分||DP||母函数||递推

    整数划分问题 整数划分是一个经典的问题. Input 每组输入是两个整数n和k.(1 <= n <= 50, 1 <= k <= n) Output 对于每组输入,请输出六行. ...

  6. 51nod p1201 整数划分

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

  7. NYOJ 746---整数划分(四)(区间DP)

    题目链接 描述 暑假来了,hrdv 又要留学校在参加ACM集训了,集训的生活非常Happy(ps:你懂得),可是他最近遇到了一个难题,让他百思不得其解,他非常郁闷..亲爱的你能帮帮他吗? 问题是我们经 ...

  8. 整数划分 (区间DP)

    整数划分(四) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 暑假来了,hrdv 又要留学校在参加ACM集训了,集训的生活非常Happy(ps:你懂得),可是他最近 ...

  9. 51nod1201 整数划分

    01背包显然超时.然后就是一道神dp了.dp[i][j]表示j个数组成i的方案数.O(nsqrt(n)) #include<cstdio> #include<cstring> ...

随机推荐

  1. ecshop 秒杀并发时库存会被减到小于0的解决办法

    ecshop 秒杀并发时库存会被减到小于0更新库存后,再进行库存检查,如果库存为负数,则执行事务的回滚. begin();//开始一个事物处理开始 $sql = "UPDATE " ...

  2. html视频播放器的代码 及其参数详解

    播放视频最实用的一段代码是: 程序代码 <"></embed></object> 其他的看参数自己修改吧 .avi格式 代码片断如下: 程序代码 < ...

  3. 每天一个linux命令(61):vi命令 /企业常用的linux命令清单

    vi/vim 的使用 基本上 vi/vim 共分为三种模式,分别是一般模式.编辑模式与指令列命令模式. 这三种模式的作用分别是: 一般模式:以 vi 打开一个档案就直接进入一般模式了(这是默认的模式) ...

  4. Java数据结构——队列

    //================================================= // File Name : Queue_demo //-------------------- ...

  5. [读书笔记]C#学习笔记二: 委托和事件的用法及不同.

    前言:  C#委托是什么 c#中的委托可以理解为函数的一个包装, 它使得C#中的函数可以作为参数来被传递, 这在作用上相当于C++中的函数指针. C++用函数指针获取函数的入口地址, 然后通过这个指针 ...

  6. 经典71道Android试题及答案

    本文为开发者奉献了70道经典Android面试题加答案--重要知识点几乎都涉及到了,你还等啥,赶紧收藏吧!! 1. 下列哪些语句关于内存回收的说明是正确的? (b) A. 程序员必须创建一个线程来释放 ...

  7. [工具类]DataTable与泛型集合List互转

    写在前面 工作中经常遇到datatable与list,对于datatable而言操作起来不太方便.所以有的时候还是非常希望通过泛型集合来进行操作的.所以这里就封装了一个扩展类.也方便使用. 类 方法中 ...

  8. 用root直接登入ubuntu 14_04

    官网下载地址:http://www.ubuntu.com/download/desktop64位桌面版:http://www.ubuntu.com/ubuntu-releases/14.04/ubun ...

  9. eclipse svn切换账号登陆问题

    1.当一个人有权限访问文件代码,而另一个账号无法访问该文件代码,要在eclipse上切换账号登陆有权限的账号时,eclipse会用缓存的账号,不会弹出从新输入新账号的窗口. 这样该怎么解决呢? 关闭e ...

  10. innerHTML和innerText

    document 对象中有innerHTML和innerText 两个属性, 这两个属性都是获取document对象的文本内容的,这两个属性间有哪些区别呢?通过几个例子来看一下. 示例1 <ht ...