发现每张卡牌最后起到作用只和是否打出去了有关。
而且每张牌打出去的概率和之前的牌打出去的情况有关。
所以我们按照牌的顺序进行DP。
然后记录$i$张牌中打出$j$张的概率,然后顺便统计答案。
直接对系数进行DP即可。
复杂度$Theta(NTR)$
#include <map> #include <ctime> #include <cmath> #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i) #define D(i,j,k) for (int i=j;i>=k;--i) double f[250][250],p[250],d[250],ans; int t,n,r; double ksm(double a,int b) { double ret=1.0; for (;b;a*=a,b>>=1) if (b&1) ret*=a; return ret; } int main() { scanf("%d",&t); while (t--) { scanf("%d%d",&n,&r); ans=0; F(i,1,n) scanf("%lf%lf",&p[i],&d[i]); F(i,1,n) F(j,1,min(n,r)) f[i][j]=0; f[0][0]=1; F(i,1,n) { f[i][0]=f[i-1][0]*ksm(1-p[i],r); F(j,1,min(n,r)) { f[i][j]=f[i-1][j-1]*(1-ksm(1-p[i],r-j+1)) +f[i-1][j]*ksm(1-p[i],r-j); ans+=f[i-1][j-1]*(1-ksm(1-p[i],r-j+1))*d[i]; } } // F(i,1,n)F(j,0,n){printf("%.10f%c",f[i][j],j==n?' ':' ');} printf("%.10f ",ans); } }