题意:都是给出每次能够赢的概率,然后每次答错问题之后要重新开始,问达完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+2*((100-pi)/100)+.....+n*((100-pi)/100)^(n-1)+.....) (有无穷次答错之后再答对的机会)
那么解释一下f[i-1]*pi/100*(1+2*((100-pi)/100)+.....+n*((100-pi)/100)^(n-1)+.....) 的意思
其实就是我这一步答错了所产生的期望步数的值
那么1*pi/100*(1+2*((100-pi)/100)+.....+n*((100-pi)/100)^(n-1)+.....) 的意思就是我这一步答对的期望
那么两个加起来就等于我当前题目的期望步数
解释完了dp的意义我们就要考虑那堆东西怎么求?
其实写过高考卷的同学都知道高考数学17题一般会有数列求和。那么这个同理(应该算比高考的简单一点),利用错位相减+等比数列求和公式可以算的结果
其中那些带有n次方的都是无限趋近于0的,我们可以直接忽略掉!!!
然后我们就会得出那堆东西的答案pi/100*(1+2*((100-pi)/100)+.....+n*((100-pi)/100)^(n-1)+.....) =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 ",f[n]); return 0; }
题目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 ",f[n]); return 0; }