我叫Ycg 2022-08-13 14:18 采纳率: 66.7%
浏览 78

关于#蓝桥杯#印章练习题的问题,如何解决?

我在做蓝桥杯 印章练习题时,在所有可能的输出数据都一样的情况下,别人的是测评结果是正确,然而我的却显示错误,只有87分,(!重点:输出数据完全一样!)

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

输入格式

  一行两个正整数n和m

输出格式

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

样例输入

2 3

样例输出

0.7500

数据规模和约定

  1≤n,m≤20

我的思路:
两个变量,应用二维数组,设dp[i][j]表示买 i 张集齐 j 种的概率。(注意不是刚好集齐 j 种);每一次买中任何一种的概率都是1/n;

第一步:确定状态

        最后一步:已经买了m-1张了,正在买这最后一张,由于除了买第一张外其他时候都有可能出现买到重复的和不是重复的两种情况,所以此时的最后一步有两种情况:

                1、前面的m-1张早已经集齐n种了,最后一张只是在买一个已经有了的种类而已

                         概率 dp[m][n] = dp[m-1][n] * 1;

                2、前面的m-1张已经集齐n-1种,而正在买的这最后一张刚好是差的那最后一种

                         概率 dp[m][n] = dp[m-1][n-1]*1/n;

        化子问题:

               1、目前正在买第 i (i<m)张,设前面的 i-1 张早已经集齐 j (j<n)种,而刚买的这张恰巧是这 j 种中的一种,买中的概率为 j/n;则有 dp[i][j] = dp[i-1][j] * j/n;

               2、目前正在买第 i (i<m)张,设前面的 i-1 张刚好集齐 j-1 (j<n)种,而刚买的这张刚好是还没有集齐的 n - (j-1) 种中的一种,买到概率为 (n-j)/n;即有 dp[i][j] = dp[i-1][j-1] *(n-j+1)/n;

第二步:状态转移

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

第三步:初始条件和边界情况

        初始条件:当 i<j 时 ,dp[i][j]=0;(买的张数都小于种类数了集齐的概率当然为 0 咯),所以初始条件必须是i>=j的情况下此方程才可行。

        边界情况:dp[0][0]=1;

第四步:计算顺序

        从已知向未知方向出发,已知dp[1][1]=1;未知dp[m][n],所以for循环顺序是1到m和1到n;

我的代码:

#include<iostream>
#include<cmath>
using namespace std;

double dp[21][21];

int main(){
    
    int n,m;
    cin>>n>>m;
    if(m<n)
        dp[m][n]=0.0;
    else{
        dp[0][0]=1.0;
        for(int i=1; i<=m; i++)
        {
            for(int j=1; j<=n; j++)
            {
                if(i<j)
                    dp[i][j]=0.0;
                else
                    dp[i][j] = dp[i-1][j]*(j*1.0/n) + dp[i-1][j-1]*((n-j+1)*1.0/n);
                
            }
        }    
        printf("%.4f\n",dp[m][n]);
    }
    return 0;
}

测评结果错误

下面是别人的完全正确的代码

#include <iostream>
#include <cmath>
using namespace std;
double dp[25][25], p;
int main()
{
    int n, m;
    cin >> n >> m;
    p = 1.0 / n;
    
    for ( int i = 1; i <= m; ++i ) {
        for ( int j = 1; j <= n; ++j ) {
            if ( i <  j ) dp[i][j] = 0;
            if ( j == 1 ) {
                dp[i][j] = pow (p, i-1);  //p^(i-1)
            }
            else {
                dp[i][j] = dp[i-1][j] * (j*1.0/n) + dp[i-1][j-1] * ((n-j+1)*1.0/n);
            }
        }
    }
    printf("%.4lf  ",dp[m][n]);
    return 0;
}

​​然后我用下面的代码对比了两个版本对应数据,输出对应不同的数据:

#include<iostream>
#include<cmath>
using namespace std;

double dp[21][21];
double dp1[25][25], p;

int main(){      //以下是所有数据对比
    int main1();//100分的 
    int main2();//87分的 
    main1();
    main2(); 

    for(int i=1; i<=20; i++)
        for(int j=1; j<=20; j++){
            if(dp[i][j]!=dp1[i][j])
                //只要对应数据不同就输出来 
                printf("%d %d %.15lf %.15lf\n",j,i,dp[i][j],dp1[i][j]);
        }
    return 0;    
} 

函数略

输出的结果居然是:

img

这是为什么呀?

  • 写回答

1条回答 默认 最新

  • StjpStjp 2022-08-14 14:57
    关注

    TLE RE MLE UE具体原因?

    评论

报告相同问题?

问题事件

  • 创建了问题 8月13日

悬赏问题

  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)
  • ¥20 matlab yalmip kkt 双层优化问题
  • ¥15 如何在3D高斯飞溅的渲染的场景中获得一个可控的旋转物体
  • ¥88 实在没有想法,需要个思路
  • ¥15 MATLAB报错输入参数太多