zoukankan      html  css  js  c++  java
  • hdu 1028 整数的划分问题

    "Well, it seems the first problem is too easy. I will let you know how foolish you are later." feng5166 says. 

    "The second problem is, given an positive integer N, we define an equation like this: 
      N=a[1]+a[2]+a[3]+...+a[m]; 
      a[i]>0,1<=m<=N; 
    My question is how many different equations you can find for a given N. 
    For example, assume N is 4, we can find: 
      4 = 4; 
      4 = 3 + 1; 
      4 = 2 + 2; 
      4 = 2 + 1 + 1; 
      4 = 1 + 1 + 1 + 1; 
    so the result is 5 when N is 4. Note that "4 = 3 + 1" and "4 = 1 + 3" is the same in this problem. Now, you do it!" 

    Input

    The input contains several test cases. Each test case contains a positive integer N(1<=N<=120) which is mentioned above. The input is terminated by the end of file. 

    Output

    For each test case, you have to output a line contains an integer P which indicate the different equations you have found. 

    Sample Input

    10 
    20

    Sample Output

    42 
    627
     
     

    思路

    假设partition(n,m):正整数n的划分中加数小于等于m的所有划分数。
    一般情况下,有:
    partion(n, m) = partition(n, m-1) + partition(n-m, m);
     
    例如:
    比如partition(7,4) = partition(7,3)+partition(3,4),为什么会加上partition(3,4)呢?
    4+3, 4+2+1,4+1+1+1这一行的总个数就是partition(3,4),
    相当于把最前面固定的4去掉,剩余项的和等于7-4=3的总个数,但同时剩余项的加数要小于4,因为这些数排在删掉的4的后面。
     
    特殊情况(递归终止条件):
    (1)partition(n,m) = partition(n,n-1) + 1
             n<=m时,有 partition(n,m) = partition(n,n-1) + 1,因为n的划分不能有大于n的加数
    (2)partition(1,n) = 1
             n = 1时,不管m有多大,整数1都只有1个划分
    (3)partition(n,1) = 1
             对任意整数n,加数小于等于1的划分只有1个,即1+1+....+1
     
    使用记忆化搜索优化递归次数,得到如下代码:
     1 #include <iostream>
     2 #include <vector>
     3 #include <stdio.h>
     4 #include <string>
     5 
     6 using namespace std;
     7 
     8 #define MAXN 150
     9 
    10 vector<vector<int>> memo;
    11 
    12 int partition(int n, int m)
    13 {
    14     if(n < 1 || m < 1)
    15         return 0;
    16     
    17     if(n == 1 || m == 1)
    18         return 1;
    19     
    20     if(memo[n][m] != -1)
    21         return memo[n][m];
    22         
    23     if(n <= m)
    24         memo[n][m] = 1+partition(n,n-1);
    25     else
    26         memo[n][m] = partition(n,m-1) + partition(n-m,m);
    27     
    28     return memo[n][m];
    29     
    30 } 
    31 
    32 int main()
    33 {
    34     int n;
    35     while(scanf("%d", &n) != EOF)
    36     {
    37         memo = vector<vector<int>>(MAXN, vector<int>(MAXN, -1));
    38         printf("%d
    ", partition(n,n));
    39     }
    40     
    41     return 0;
    42 }

     
     
  • 相关阅读:
    C++获得系统路径
    HDU
    直接插入排序
    《python基础教程(第二版)》学习笔记 函数(第6章)
    《python基础教程(第二版)》学习笔记 语句/循环/条件(第5章)
    《python基础教程(第二版)》学习笔记 字典(第4章)
    《python基础教程(第二版)》学习笔记 字符串(第3章)
    《python基础教程(第二版)》学习笔记 列表/元组(第2章)
    R语言 使用命令行参数运行R程序
    add new row to data.frame/dataframe
  • 原文地址:https://www.cnblogs.com/FengZeng666/p/12663187.html
Copyright © 2011-2022 走看看