我叫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 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化
  • ¥15 Mirare PLUS 进行密钥认证?(详解)
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥20 想用ollama做一个自己的AI数据库
  • ¥15 关于qualoth编辑及缝合服装领子的问题解决方案探寻
  • ¥15 请问怎么才能复现这样的图呀