20190716-T1-礼物

呵呵,我暴力WA

这个题充分考验了大家对数学的理解(麦蒙大多在胡诌

但是确实如此啊。

看数据范围想状压。(我额嗯嗯想到暴力?)

然后设出一个可爱的$dp$式(主语当然不是我,是出题人大佬)

$f_s$表示二进制组昂态(状态)为$s$时的期望。

那么我们可以从$s'$转移过来,其中$s'  or\   s = s$或$s'   and\   s =s$($and$和$or$均为位运算)(内两个式子是等效的)

那么有:

$f_s= \sum\limits_{i=1}^N p_i \times f_{s'}+(1-\sum \limits_{i=1}^N p_i) \times f_s +1$

真是恐怖,$f_s$转移需要自己~

但是表慌,数学老师可以拯救你,哒哒哒

移项。式子变为:

$\begin{array}{lcl}0 & = & \sum \limits_{i=1}^N p_i \times f_{s'}-f_s \times \sum \limits_{i=1}^N p_i +1\\f_s & = & \frac{\sum \limits_{i=1}^N p_i \times f_{s'}+1}{\sum \limits_{i=1}^N p_i}\end{array}$

还是比较简单的。

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 
 5 //#include "debug.h"
 6 
 7 #define N 22
 8 using namespace std;
 9 int n;
10 double p[N];
11 long long val,dat;
12 double dp[(1<<20)+20];
13 int main(){
14     scanf("%d",&n);
15     for (int i=1;i<=n;i++){
16         scanf("%lf%lld",&p[i],&dat);
17         val=val+dat;
18     }
19     cout<<val<<endl;
20     double ons=0,sums=0;
21     for (int s=0;s<1<<n;s++){
22         ons=sums=0;
23         for (int i=1;i<=n;i++){
24             if (s&(1<<(i-1))){
25                 ons+=dp[s^(1<<(i-1))]*p[i];//cout<<bin(s,n)<<"<<"<<bin(s^(1<<(i-1)),n)<<endl;
26                 sums+=p[i];//cout<<sums<<endl;
27             }
28         }//cout<<"O:"<<ons<<"  S:"<<sums<<endl;
29         if(sums==0){
30     //        cout<<"T0T"<<NL;
31             continue;
32         }
33         dp[s]=(ons+1.0)/sums;
34     }
35 //    pour(dp,1,1<<n,10,"Dp");
36     printf("%.3lf\n",dp[(1<<n)-1]);
37     return 0;
38 }
View Code

 

posted @ 2019-07-17 06:16  Miemeng_麦蒙  阅读(103)  评论(0编辑  收藏  举报

小麦在雨中,蒙蒙的雾气

麦蒙不想有人骚扰他,如果有必要 联系 QQ:1755601414

如果你嫌广告大,那就喷我吧,不是博客园的锅。