f[i][j]表示给[i,n]区间的卡牌j次机会的概率。单独考虑每一张牌的情况,而不是单独考虑每一轮的情况
f[0][r]=1;
f[i][j]=f[i-1][j]*sig(i-1,j)+f[i-1][j+1]*(1-sig(i-1,j+1))
其中sig[i][j]表示第i张牌,j次机会,都没有发出去的概率。
注意数组清0
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #define ll long long #define inf 1e9 #define eps 1e-10 #define md #define N 500 using namespace std; long double p[N],f[N][N],g[N][N],a[N]; int main() { #ifndef ONLINE_JUDGE freopen("data.in","r",stdin); freopen("data.out","w",stdout); #endif int tt; scanf("%d",&tt); while (tt--) { int n,R; scanf("%d%d",&n,&R); for (int i=1;i<=n;i++) { double x,y; scanf("%lf%lf",&x,&y); p[i]=x; a[i]=y; } memset(f,0,sizeof(f)); memset(g,0,sizeof(g)); for (int i=1;i<=n;i++) { g[i][0]=1; p[i]=1.0-p[i]; for (int j=1;j<=R;j++) g[i][j]=g[i][j-1]*p[i]; } f[0][R]=1; long double ans=0; g[0][R]=1; for (int i=1;i<=n;i++) { for (int j=1;j<=R;j++) { f[i][j]=f[i-1][j+1]*(1-g[i-1][j+1])+f[i-1][j]*g[i-1][j]; //printf("%.3lf ",f[i][j]); ans=ans+f[i][j]*(1-g[i][j])*a[i]; } //printf("\n"); } printf("%.10lf\n",(double)ans); } return 0; }