zoukankan      html  css  js  c++  java
  • 2014北大研究生推免机试(校内)-复杂的整数划分(DP进阶)

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

    Openjudge 原题网址:Bailian2014研究生推免上机考试(校内)

    原题:

      Description

      将正整数n 表示成一系列正整数之和,n=n1+n2+…+nk, 其中n1>=n2>=…>=nk>=1 k>=1
      正整数n 的这种表示称为正整数n 的划分。

      Input
      标准的输入包含若干组测试数据。每组测试数据是一行输入数据,包括两个整数N 和 K。   
      (0 < N <= 50, 0 < K <= N)
      Output
      对于每组测试数据,输出以下三行数据:
      第一行: N划分成K个正整数之和的划分数目
      第二行: N划分成若干个不同正整数之和的划分数目
      第三行: N划分成若干个奇正整数之和的划分数目  
      Sample Input
      5 2
      Sample Output
      2
      3
      3
      Hint  
      第一行: 4+1, 3+2,
      第二行: 5,4+1,3+2
      第三行: 5,1+1+3, 1+1+1+1+1+1

      有关这三种变形问题的具体解释在我的另一篇随笔中有提及:整数划分问题-解法汇总,看不懂Code的ACMer见这篇随笔。

      

      Code如下:

      

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 
     6 #define MAX 51
     7 
     8 int dp1[MAX][MAX];
     9 int dp2[MAX][MAX];
    10 int dp3[MAX][MAX];
    11 
    12 /*划分成K个整数*/
    13 void DP1()
    14 {
    15     for (int n = 1; n < MAX; n++)
    16     {
    17         for (int k = 1; k < MAX; k++)
    18         {
    19             if (n == k || k == 1)
    20                 dp1[n][k] = 1;
    21             else if (n > k)
    22                 dp1[n][k] = dp1[n - k][k] + dp1[n - 1][k - 1];    //划分中不包含1 + 划分中至少有一个1
    23         }
    24     }
    25 }
    26 
    27 /*划分成<=m的不同整数*/
    28 void DP2()
    29 {
    30     for (int n = 1; n < MAX; n++)
    31     {
    32         for (int m = 1; m < MAX; m++)
    33         {
    34             if (n > m)    //除m外的数不包括m(即剩下划分总和为n-m中没有m)
    35                 dp2[n][m] = dp2[n - m][m - 1] + dp2[n][m - 1];
    36             else if (n < m)
    37                 dp2[n][m] = dp2[n][n];
    38             else
    39                 dp2[n][m] = 1 + dp2[n][m - 1];
    40         }
    41     }
    42 }
    43 
    44 /*划分成<=m的奇正整数*/
    45 void DP3()
    46 {
    47     for (int n = 1; n < MAX; n++)    //+1不会增加种类
    48     {
    49         for (int m = 1; m < MAX; m+=2)
    50         {
    51             if (n > m)
    52                 dp3[n][m] = dp3[n - m][m] + dp3[n][m - 1];
    53             else if (n < m)
    54                 dp3[n][m] = dp3[n][n];
    55             else
    56                 dp3[n][m] = 1 + dp3[n][m - 1];
    57             dp3[n][m + 1] = dp3[n][m];
    58         }
    59     }
    60 }
    61 
    62 int main()
    63 {
    64     DP1();
    65     DP2();
    66     DP3();
    67     int num, k;
    68     while (scanf("%d%d", &num, &k) != EOF)
    69     {
    70         printf("%d
    ", dp1[num][k]);
    71         printf("%d
    ", dp2[num][num]);
    72         printf("%d
    ", dp3[num][num]);
    73     }
    74 
    75     return 0;
    76 }
    小墨-原创
    他坐在湖边,望向天空,她坐在对岸,盯着湖面
  • 相关阅读:
    PAT甲级——A1113 Integer Set Partition
    PAT甲级——A1112 Stucked Keyboard【20】
    PAT甲级——A1111 Online Map【30】
    左神算法书籍《程序员代码面试指南》——2_12将搜索二叉树转换成双向链表【★★】
    PAT甲级——A1110 Complete Binary Tree【25】
    PAT甲级——A1109 Group Photo【25】
    PAT甲级——A1108 Finding Average【20】
    左神算法书籍《程序员代码面试指南》——2_12将搜索二叉树转换成双向链表
    PAT甲级——A1107 Social Clusters
    shiro 框架
  • 原文地址:https://www.cnblogs.com/Inkblots/p/4854519.html
Copyright © 2011-2022 走看看