绳结-动态规划-蓝桥杯2014年JavaA组/C++ c组

题目描述如下:

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
今有 100100 根绳子,当然会有 200200 个绳头。
如果任意取绳头两两配对,把所有绳头都打结连接起来。最后会形成若干个绳圈(不考虑是否套在一起)。
我们的问题是:请计算最后将形成多少个绳圈的概率最大?
运行限制
最大运行时间:1s
最大运行内存: 128M

蓝桥云课给题目打的tag是简单,但是题目的通过率却只有百分之十,可以看出题目难度还是蛮高滴。
不要被简单两个字骗了!!
在这里插入图片描述

这道题是典型的动态规划题目,寻找递推关系即可。
计算概率,先寻找,i个绳子可以有多少种打结方式。
设i-1根绳子有sum[i-1]种打结方式,则可得:
在这里插入图片描述
如图所示,i根绳子有sum[i-1]*(2i-1)种打结方式。
再计算,如有i根绳子,打结成x个圈有几种打结方式,递推方式如下表:
在这里插入图片描述
此时,根据此递推关系,即可得出i根绳子,形成每种圈数的打结方式数量,将打结方式除以i根绳子的打结方式总数量,即可的带该圈数形成的概率,寻找概率最高者即得题目答案。
或者直接寻找不同圈数打结方式数量的最大值,拥有最大值者即概率最大者。
Java代码如下:

import java.util.*;

public class Sj {
    public static void main(String[] args) {
        //计算100个绳子可以生成多少种打结方式
        double[] sum = new double[101];
        sum[1] = 1;
        for (int i = 2; i < sum.length; i++) {
            sum[i] = sum[i-1] * (2*i - 1);
        }
        double countOf100 = sum[100];//100个绳子可以进行的打结方式数量
        double[][] c = new double[101][101];
        c[1][1] = 1;//递推空间初始化
        for (int i = 2; i < 101; i++) {
            for (int j = 1; j < i + 1; j++) {
                if (j == 1){
                    c[i][j] = c[i-1][j] * (i - 1) * 2;
                    continue;
                }
                if (j == i){
                    c[i][j] = 1;
                    continue;
                }
                c[i][j] = c[i-1][j-1] + c[i-1][j] * (i-1) * 2;
            }
            //System.out.println("第" + i + "根绳子 " + Arrays.toString(c[i]));
        }
        //c[100]中即每种圈数的打结方式数量
        /*对c[100]进行排序*/
        Map<Integer,Double> map = new HashMap<>();
        for (int i = 1; i < 101; i++) {
            map.put(i, c[100][i]);
        }
        Comparator<Map.Entry<Integer, Double>> comparator = new Comparator<Map.Entry<Integer, Double>>() {
            @Override
            public int compare(Map.Entry<Integer, Double> o1, Map.Entry<Integer, Double> o2) {
                return (int) (o1.getValue() - o2.getValue());
            }
        };
        Set<Map.Entry<Integer,Double>> sort = new TreeSet<>(comparator);
        for (Map.Entry<Integer, Double> entry : map.entrySet()) {
            sort.add(entry);
        }
        for (Map.Entry<Integer, Double> entry: sort){
            System.out.println(entry.getKey() + " is " + entry.getValue());
        }
    }
}

结果如下:
在这里插入图片描述
即,形成3圈的概率最大。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值