当前位置:   article > 正文

分月饼--动态规划--Java

分月饼--动态规划--Java

题目

中秋节,公司分月饼,m个员工,买了n个月饼,m <= n,每个员工至少分1个月饼,但可以分多个,单人分到最多月饼的个数是Max1,单人分到第二多月饼个数是Max2,Max1-Max2 <= 3,单人分到第n-1多月饼个数是Max(n-1),单人分到第n多月饼个数是Max(n),Max(n-1)- Max(n) <= 3,问有多少种分月饼的方法?

输入描述:

每一行输入m,n,表示m个员工,n个月饼,m <=n

输出描述:

输出有多少种分法

示例1:

输入

2 4

输出

2

说明

4=1+3

4=2+2

注意:1+3和3+1要算成同一种分法

示例2:

输入

3 5

输出

2

说明

5=1+1+3

5=1+2+3

示例3:

输入

3 12

输出

6

说明

满足要求的6种分法:

1、12 = 1 + 1 + 10 (Max1=10, Max2=1,不满足Max1-Max2 <= 3的约束)

2、12 = 1 + 2 + 9 (Max1=9,Max2=2,不满足Max1-Max2 <= 3的约束)

3、12 = 1 + 3 + 8 (Max1=8,Max2=3,不满足Max1-Max2 <= 3的约束)

4、12 = 1 + 4 + 7 (Max1=7,Max2=4,Max3=1, 满足要求)

5、12 = 1 + 5 + 6 (Max1=6,Max2=5,Max3=1, 不满足要求)

6、12 = 2 + 2 + 8 (Max1=8,Max2=2,不满足要求)

7、12 = 2 + 3 + 7 (Max1=7,Max2=3,不满足要求)

8、12 = 2 + 4 + 6 (Max1=6,Max2=4,Max3=2, 满足要求)

9、12 = 2 + 5 + 5 (Max1=5,Max2=2 满足要求)

10、12 = 3 + 3 + 6 (Max1=6,Max2=3 满足要求)

11、12 = 3 + 4 + 5 (Max1=5,Max2=4,Max3=3 满足要求)

12 = 4 + 4 + 4 (Max1=4,满足要求)

思路

动态规划做法

1.状态表示

dp[i][j][k]:前i个人已经分了j个月饼,且第i个人分到了k个月饼。(1<=i<=m,i<=j<=n,1<=k<j)

2.初始值

dp[1][k][k]=1:第一个人分到k个月饼的方案数为1。(1<=k<=n)

3.转态转移方程

这题方案数的计算方式是不同数字的组合方式,不考虑数字的顺序,因此我们直接按照从小到大来分月饼即可,即找到一个不严格单调递增的正整数数列。

dp[i][j][k]+=dp[i-1][j-k][l];前i个人已经分了j个月饼且第i个人分到了k个月饼的方案数=前i-1个人已经分了j-k个月饼且第i-1个人分到了l个月饼的方案数总和。( l ∈[max(k-3,1),k],只考虑第i-1个人分到的月饼数比第i人分到的月饼数相差不超过3的方案)

4.答案

ans=dp[m][n][1]+dp[m][n][2]+...+dp[m][n][n]

代码

  1. import java.util.Scanner;
  2. /**
  3. * @author jn
  4. * @version 1.0
  5. * @description: TODO
  6. * @date 29/6/2024 下午5:20
  7. */
  8. public class DivideMooncake {
  9. public static void main(String[] args) {
  10. Scanner scan=new Scanner(System.in);
  11. int m=scan.nextInt();//员工
  12. int n=scan.nextInt();//月饼
  13. int[][][] dp=new int[m+1][n+1][n+1];
  14. //dp[i][j][k]
  15. for (int k = 1; k <=n; k++) {
  16. dp[1][k][k]=1;
  17. }
  18. for (int i = 1; i <=m; i++) {
  19. for (int j = i; j <=n ; j++) {
  20. for (int k = 1; k < j; k++) {
  21. for (int l = Math.max(k-3,1); l<=k; l++) {
  22. dp[i][j][k]+=dp[i-1][j-k][l];
  23. }
  24. }
  25. }
  26. }
  27. int ans=0;
  28. for (int i = 1; i <=n; i++) {
  29. ans+=dp[m][n][i];
  30. }
  31. System.out.println(ans);
  32. }
  33. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/798366
推荐阅读
相关标签
  

闽ICP备14008679号