题意呢 就是有两种售票方式 一种是icpc 一种是其他方式 icpc抢票成功的概率是其他方式的2倍……
这时 一个人出现了 他通过内幕知道了两种抢票方式各有多少人 他想知道自己如果用icpc抢票成功的概率是多少 用acm抢票成功的概率是多少……
做过不多的概率dp 还在摸索……
dp[i][j]代表第i轮有j个icpc的人已经有票了……
当然同时i-j个通过其他方式抢票的人也有票了 这就是用同样的函数搜两次的原理……
优化一次i<=a 一次是把初始化放到for里……
第一次见这么卡时间的题……
把dp数组的优化放到for里就过了……
1 #include<stdio.h> 2 #include<iostream> 3 #include<algorithm> 4 #include<math.h> 5 #include<string.h> 6 #include<string> 7 #include<map> 8 #include<vector> 9 #include<queue> 10 #define M(a,b) memset(a,b,sizeof(a)) 11 using namespace std; 12 double dp[3005][3005]; //i轮j个有票 13 bool ok=false; 14 double solve(int a,int b,int c){ 15 double n=(double)a; 16 double icpc=(double)b; 17 double acm=(double)c; 18 if(n>icpc+acm) n=icpc+acm; 19 if(a>b+c) a=b+c; 20 dp[0][0]=1; 21 for(int i=1;i<=n;i++){ 22 dp[i][0]=0; //优化初始化就过了 23 dp[i][0]+=dp[i-1][0]*(acm-i+1.0)/(acm-i+1.0+icpc*2.0); 24 } 25 for(int i=1;i<=n;i++){ 26 dp[i][i]=0; 27 dp[i][i]+=dp[i-1][i-1]*((icpc-i+1.0)*2.0)/(acm+(icpc-i+1.0)*2.0); 28 } 29 for(int i=2;i<=n;i++){ 30 for(int j=1;j<i&&j<=a;j++){ 31 dp[i][j]=0; 32 //这里还可以优化 33 dp[i][j]+=dp[i-1][j]*(acm-(i-j-1.0))/(acm-(i-j-1.0)+(icpc-j)*2.0); 34 dp[i][j]+=dp[i-1][j-1]*((icpc-j+1.0)*2.0)/(acm-(i-j)+(icpc-j+1.0)*2.0); 35 } 36 } 37 double ans=0; 38 for(int i=0;i<=n&&i<=a;i++) 39 if(ok)ans+=(dp[a][i])*i/icpc; 40 else ans+=(dp[a][i])*(n-i)/acm; 41 return ans; 42 } 43 44 int main(){ 45 int n,icpc,acm; 46 while(~scanf("%d",&n)){ 47 if(n==0) break; //这里不加应该也可以 48 scanf("%d%d",&icpc,&acm); 49 if(icpc==0&&acm==0){ 50 printf("1.0000000000000000 "); 51 printf("1.0000000000000000 "); 52 continue; 53 } 54 ok=true; 55 printf("%.16lf ",solve(n,icpc+1,acm)); 56 ok=false; 57 printf("%.16lf ",solve(n,icpc,acm+1)); 58 } 59 return 0; 60 }