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如下:

  

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

 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\n", dp1[num][k]);
71         printf("%d\n", dp2[num][num]);
72         printf("%d\n", dp3[num][num]);
73     }
74 
75     return 0;
76 }

小墨-原创

 

    原文作者:Inkblots
    原文地址: https://www.cnblogs.com/Inkblots/p/4854519.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞