两道一样的经典概率题

题目链接1:

题目链接2:

题意:都是给出每次能够赢的概率,然后每次答错问题之后要重新开始,问达完n个问题的最小期望数

(以下题解以第一道题为例,第二道同理)

题解:其实很容易想得到我们令f[i]为答对i道题的期望步数是多少,那么我们只要找出f[i+1]与f[i]的关系即可进行线性递推

了解离散性概率的人都知道期望怎么表示

E(X)=x1*Px1+x2*Px2+.....+xn*Pxn

那么我们答对i道题的步数是什么?

很明显是以f[i-1]为基础进行第i次的答题,那么f[i]={f[i-1]+1}*pi/100*(1*pi+2*pi+.....+n*pi+.....)  (有无穷次答错之后再答对的机会)

那么解释一下f[i-1]*pi/100*(1*pi+2*pi+.....+n*pi+.....)  的意思

其实就是我这一步答错了所产生的期望步数的值

那么1*pi/100*(1*pi+2*pi+.....+n*pi+.....) 的意思就是我这一步答对的期望

那么两个加起来就等于我当前题目的期望步数

解释完了dp的意义我们就要考虑那堆东西怎么求?

其实写过高考卷的同学都知道高考数学17题一般会有数列求和。那么这个同理(应该算比高考的简单一点),利用错位相减+等比数列求和公式可以算的结果

其中那些带有n次方的都是无限趋近于0的,我们可以直接忽略掉!!!

然后我们就会得出那堆东西的答案pi/100*(1*pi+2*pi+.....+n*pi+.....) =100/pi (卧槽老子化简了这么久最后答案这么短,坑爹呢!!!)

然后问题就解决了!!!  第二道题其实就是分母不为100,为输入的数字,其实一点影响木有。只要把100换成那个他输入的数字就行了

题目1代码:

#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#include <tr1/unordered_map>
using namespace std;
#define ll long long
#define re register
#define pb push_back
#define fi first
#define se second
const int N=1e6+10;
const int mod=998244353;
void read(int &a)
{
    a=0;int d=1;char ch;
    while(ch=getchar(),ch>'9'||ch<'0')
        if(ch=='-')
            d=-1;
    a=ch^48;
    while(ch=getchar(),ch>='0'&&ch<='9')
        a=(a<<3)+(a<<1)+(ch^48);
    a*=d;
}
ll quickmod(int x,int y)
{
    ll res=1,base=x;
    while(y)
    {
        if(y&1) res=res*base%mod;
        base=base*base%mod;
        y>>=1;
    }
    return res;
}
ll f[N];
int main()
{
    int n;
    read(n);
    f[0]=0;
    for(re int i=1,x;i<=n;i++)
    {
        read(x);
        f[i]=(f[i-1]+1)*100%mod*quickmod(x,mod-2)%mod;
    }
    printf("%I64d\n",f[n]);
    return 0;
}
View Code

题目2代码:

#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#include <tr1/unordered_map>
using namespace std;
#define ll long long
#define re register
#define pb push_back
#define fi first
#define se second
const int N=1e6+10;
const int mod=1e9+7;
void read(int &a)
{
    a=0;int d=1;char ch;
    while(ch=getchar(),ch>'9'||ch<'0')
        if(ch=='-')
            d=-1;
    a=ch^48;
    while(ch=getchar(),ch>='0'&&ch<='9')
        a=(a<<3)+(a<<1)+(ch^48);
    a*=d;
}
ll quickmod(int x,int y)
{
    ll res=1,base=x;
    while(y)
    {
        if(y&1) res=res*base%mod;
        base=base*base%mod;
        y>>=1;
    }
    return res;
}
ll f[N];
int main()
{
    int n;
    read(n);
    for(re int i=1,x,y;i<=n;i++)
    {
        read(x);read(y);
        f[i]=(f[i-1]+1)*y%mod*quickmod(x,mod-2)%mod;
    }
    printf("%lld\n",f[n]);
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/acm1ruoji/p/11997230.html