zoukankan      html  css  js  c++  java
  • 华为OJ平台——放苹果(典型整数划分问题)

    题目描述:

    输入m,n,分别表示苹果数与盘子的总数,要求输出苹果放在n个盘子的方法总数(注意511和151是一种情况),例如输入 7 3 输出8((7),(6,1),(5,2),(4,3),(5,1,1),(4,2,1),(3,3,1),(3,2,2))

    思路:

    最典型的解法整数分解,例如给定n个苹果,把苹果放到k个盘子里,允许有的盘子为空,不妨设 f(n , k ) (边缘条件为当 n = 0 ,1时,返回1,当 k = 1 时,返回1)表示结果,分析一下可以知道有两种放的方法,一种是有空盘,一种是没空盘。

    没空盘的情况可以知道每个盘子里至少有一个苹果,也就是说这种情况的总数为 f ( n-k , k ) 。

    而有空盘的情况,我们可以假设最后一个盘子为空,则这种情况的总数为f ( n , k-1 ) (无需考虑多个盘子为空的情况,递归时必然会出现)

    所以状态转移方程为 f ( n , k ) = f ( n-k , k ) + f ( n , k-1 )

     1 import java.util.Scanner;
     2 
     3 /**
     4  * 把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,
     5  * 问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
     6  */
     7 public class PlayApples {
     8 
     9     public static void main(String[] args) {
    10         //输入读取参数
    11         Scanner cin = new Scanner(System.in) ;        
    12         int apples = cin.nextInt() ;
    13         int planes = cin.nextInt() ;
    14         cin.close();
    15         
    16         System.out.println(count(apples,planes)) ;
    17 
    18     }
    19 
    20     /**
    21      * 最典型的整数分解
    22      * 例如给定n个苹果,把苹果放到k个盘子里,允许有的盘子为空, 不妨设 f(m , n ) 
    23      * (边缘条件为当 m == 0 ,1时,返回1,当 n == 1 时,返回1)表示结果,
    24      * 分析一下可以知道有两中放的方法,一种是有空盘,一种是没空盘,
    25      * 没空盘的情况可以知道每个盘子里至少有一个苹果,也就是说这种情况的总数为 f ( n-k , k ) 。
    26      * 而有空盘的情况,我们可以假设最后一个盘子为空,则这种情况的总数为f ( n , k-1 ) (无需考虑多个盘子为空的情况,递归时必然会出现)
    27      * 所以状态转移方程为 f ( n , k ) = f  ( n-k , k ) +  f ( n , k-1 )。
    28      * 
    29      * 而如果是不允许有空盘子的情况,则可以由上面的情况推出,
    30      * 设 d ( n , k ) 表示把n个苹果放到k个盘子里,不允许有空盘子的方法总数,
    31      * 则有f ( n , k ) =  Σ (  1 <= i <= k ) d ( n , i ) 
    32      * 所以 d ( n , k ) = f ( n , k ) - f ( n , k-1 )
    33      * 
    34      * @param m  苹果数量
    35      * @param n  盘子数量
    36      * @return
    37      */
    38     private static int count(int m, int n) {
    39         //n为0 是错误的,故返回0
    40         if(n == 0){
    41             return 0 ;
    42         }
    43         //m == 0,1时和 n == 1时均只有一种放法
    44         if(m == 0 || n == 1 || m == 1 ){
    45             return 1 ;
    46         }else if(m < 0){
    47             //m < 0 时,也是错误的情形,所以返回0
    48             return 0 ;
    49         }else{
    50             //递归调用
    51             return count(m-n,n) + count(m,n-1) ;
    52         }    
    53     }
    54 }
    Code

    扩展:

    如果是不允许有空盘子的情况,则可以由上面的情况推出,设 d ( n , k ) 表示把n个苹果放到k个盘子里,不允许有空盘子的方法总数,则有

    f ( n , k ) = Σ ( 1 <= i <= k ) d ( n , i ) 所以 d ( n , k ) = f ( n , k ) - f ( n , k-1 )

  • 相关阅读:
    1.两数之和
    [Udemy] ES 7 and Elastic Stack
    [Udemy] ES 7 and Elastic Stack
    Common Linux Commands 日常工作常用Linux命令
    ELK 学习
    web 3d 技术预研及数据可视化技术
    AWS Cloud Practioner 官方课程笔记
    怎么用 pytorch 查看 GPU 信息
    ECG 项目预研
    怎么查看keras 或者 tensorflow 正在使用的GPU
  • 原文地址:https://www.cnblogs.com/mukekeheart/p/5594225.html
Copyright © 2011-2022 走看看