蓝桥杯,印章Java实现

该篇文章提供了Java代码实现,通过动态规划方法计算在资源限制下购买印章凑齐指定种数的概率,适用于IT技术中概率问题的求解。
摘要由CSDN通过智能技术生成

题目描述:

资源限制

内存限制:256.0MB   C/C++时间限制:1.0s   Java时间限制:3.0s   Python时间限制:5.0s

问题描述

  共有n种图案的印章,每种图案的出现概率相同。小A买了m张印章,求小A集齐n种印章的概率。

输入格式

  一行两个正整数n和m

输出格式

  一个实数P表示答案,保留4位小数。

样例输入

2 3

样例输出

0.7500

数据规模和约定

  1≤n,m≤20

解题方法:

动态规划五部曲:

①确定dp数组的含义:

dp[m][n],表示买m张印章凑齐n种的概率

②dp数组数组的递推公式:

p=1/n;对应的概率

有两种情况组成dp[i][j],

1.在买当前第i张之前,也就是已经买了i-1张,此时已经凑到了j种,再抽一张还是j种,其对应的概率为j*p,dp[i][j]=dp[i-1][j]*j*p;

2.在买当前第i张之前,也就是已经买了i-1张,此时只凑到了j-1种,再抽一张才是j种,其对应的概率为[n-(j-1)]*p,dp[i][j]=dp[i-1][j-1]*(n-j+1)*p;

那么,dp[i][j]的结果就是这两个结果的和:

dp[i][j]=dp[i-1][j]*j*p+dp[i-1][j-1]*(n-j+1)*p;

③dp数组的初始化:

1)当买的印章数<印章的种数,i<j,那么其对应的概率为0,因为只买i张,不可能凑到j种

此时dp[i][j]=0;

2)当印章种数为1,也就是j=1,那么买一张是1种的概率为1,买第二张还是1种的概率为p,因为要保证买到的第二张和第一张是一样的,所以概率为p

此时dp[i][j]=Math.pow(p,i-1);

④dp数组的遍历顺序:

外层遍历张数,内层遍历印章的种类

⑤测试验证

​

import java.util.*;

public class _Main{
    /**

     *  共有n种图案的印章,每种图案的出现概率相同。小A买了m张印章,求小A集齐n种印章的概率。
     **/
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        //定义p代表每一次的概率
        double p = 1.0 / n;
        //定义dp数组 dp[m][n] 买m张凑齐n种的概率
        double[][] dp = new double[m + 1][n + 1];
        //i代表买了i张 j代表凑齐j种
        for (int i = 1; i <=m; i++) {//外层遍历买了多少张
            for (int j = 1; j <=n; j++) {//内层遍历对应的多少种
                //初始化dp数组
                //如果数量<种类,那么肯定是凑不齐的,那么对应的概率为0
                if (i<j)
                    dp[i][j]=0;
                if (j==1)//全部的印章只凑一种
                    dp[i][j]=Math.pow(p,i-1);//第一次取到1种的概率为1,第二次取到和第一张一样的概率为p
                else {
                    /**
                     * 两种情况:
                     * ①再抽第i张牌之前,已经凑到了j种,再抽一张凑到j种的概率为j*p,dp[i][j]=dp[i-1][j]*(j*p)
                     * ②再抽第i张牌,刚好凑到了j种,说明手里面的牌为j-1种,剩下的种数为[n-(j-1)]种,再抽一张凑到j种的概率为[n-(j-1)]*p,dp[i][j]=dp[i-1][j-1]*(n-j+1)*p
                     */
                    dp[i][j]=dp[i-1][j]*(j*p)+dp[i-1][j-1]*(n-j+1)*p;
                }

            }
        }
        System.out.printf("%.4f",dp[m][n]);
    }
}


​

输出结果正确。

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值