几道期望题

Double PatiencePOJ - 2794 

一个水题,但是我的状压被卡T了,记忆化搜索能过。。

 1 //Achen
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<vector>
 7 #include<cstdio>
 8 #include<queue>
 9 #include<cmath>
10 #include<set>
11 #define For(i,a,b) for(int i=(a);i<=(b);i++)
12 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
13 const int up=1953125;
14 typedef long long LL; 
15 typedef double db;
16 using namespace std;
17 char s[15][10][10];
18 int power[20],vis[up+1];
19 db f[up+7];
20 
21 template<typename T> void read(T &x) {
22     char ch=getchar(); x=0; T f=1;
23     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
24     if(ch=='-') f=-1,ch=getchar();
25     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
26 }
27 
28 db dp(int u) {
29     if(vis[u]) return f[u];
30     vis[u]=1;
31     int a[10],cnt=0;
32     for(int i=1,t=u;i<=9;i++,t/=5) a[i]=t%5;
33     For(i,1,9) 
34         For(j,i+1,9) 
35             if(a[i]&&a[j]&&s[i][a[i]][0]==s[j][a[j]][0]) {
36                 cnt++;
37                 f[u]+=dp(u-power[j-1]-power[i-1]);
38             } 
39        if(cnt) f[u]/=(db)cnt;
40     return f[u];
41 }
42 
43 int main() {
44     power[0]=1;
45     For(i,1,9) power[i]=power[i-1]*5;
46     For(i,1,9) 
47         For(j,1,4) 
48             scanf("%s",s[i][j]);
49     f[0]=1.0;
50     printf("%.6f",dp(up-1));
51     return 0;
52 }
View Code

 

hdu3689Infinite monkey theorem

又是一道大水题,直接对询问串跑kmp,然后暴力dp转移

 

  1 Time limit
  2     1000 ms
  3 Memory limit
  4     32768 kB
  5 OS
  6     Windows
  7 Source
  8     2010 Asia Hangzhou Regional Contest 
  9 
 10 Result     Time
 11 Accepted     3 days ago
 12 More...
 13 Descriptions:
 14 
 15     System Crawler 2018-04-18
 16          
 17 
 18 Infinite monkey theorem
 19 HDU - 3689
 20 Preview:
 21 All Copyright Reserved ©2018 Xu Han
 22 Server Time: 2018-04-23 18:55:29 CST
 23 #13571834 | achenachen's solution for [HDU-3689]
 24 Status    Accepted
 25 Time    15ms
 26 Memory    9668kB
 27 Length    1547
 28 Lang    G++
 29 Submitted    2018-04-20 10:15:50
 30 Shared    
 31 RemoteRunId    24491353
 32 Select Code
 33 
 34 //Achen
 35 #include<algorithm>
 36 #include<iostream>
 37 #include<cstring>
 38 #include<cstdlib>
 39 #include<vector>
 40 #include<cstdio>
 41 #include<queue>
 42 #include<cmath>
 43 #include<set>
 44 #define For(i,a,b) for(int i=(a);i<=(b);i++)
 45 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
 46 typedef long long LL; 
 47 typedef double db;
 48 using namespace std;
 49 int n,m;
 50 db p[30],f[1007][1007],tpp;
 51 char s[10007];
 52 
 53 template<typename T> void read(T &x) {
 54     char ch=getchar(); x=0; T f=1;
 55     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
 56     if(ch=='-') f=-1,ch=getchar();
 57     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
 58 }
 59 
 60 int nxt[1007];
 61 void make_nxt(int n) {
 62     for(int i=1,k=0;i<n;i++) {
 63         while(k&&s[i]!=s[k]) k=nxt[k-1];
 64         if(s[i]==s[k]) k++;
 65         nxt[i]=k;
 66     }
 67 }
 68 
 69 int main() {
 70 #ifdef DEBUG
 71     freopen(".in","r",stdin);
 72     freopen(".out","w",stdout);
 73 #endif
 74     for(;;) {
 75         read(n); read(m);    
 76         if(n==0&&m==0) break;
 77         For(i,0,25) p[i]=0;
 78         For(i,1,n) {
 79             scanf("%s",s);
 80             scanf("%lf",&tpp);
 81             p[s[0]-'a']=tpp;
 82         }
 83         scanf("%s",s);
 84         int len=strlen(s);
 85         if(len>m) puts("0.00%");
 86         else {
 87             make_nxt(len);
 88             memset(f,0,sizeof(f));
 89             f[0][0]=1;
 90             For(i,0,m-1) 
 91                 For(j,0,len-1) if(f[i][j]!=0) {
 92                     For(k,0,25) if(p[k]!=0) {
 93                         int now=j;
 94                         while(now&&s[now]-'a'!=k) now=nxt[now-1];
 95                         if(s[now]-'a'==k) now++;
 96                         f[i+1][now]+=f[i][j]*p[k];
 97                     }    
 98                 }
 99             db ans=0;
100             For(i,len,m) ans+=f[i][len];
101             ans*=100;
102             printf("%.2lf",ans);
103             puts("%");
104         }
105     }
106     return 0;
107 }
View Code

 

 

bzoj2337: [HNOI2011]XOR和路径

把每个二进制位拆开考虑.

f[x]表示从x走到n得到1的概率

ans=(1<<i)*f[1]

高斯消元解出f即可

写的第一道高斯消元的题

 1 //Achen
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<vector>
 7 #include<cstdio>
 8 #include<queue>
 9 #include<cmath>
10 #include<set>
11 #define For(i,a,b) for(int i=(a);i<=(b);i++)
12 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
13 const int N=10007;
14 typedef long long LL; 
15 typedef double db;
16 using namespace std;
17 int n,m,mxw;
18 
19 template<typename T> void read(T &x) {
20     char ch=getchar(); x=0; T f=1;
21     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
22     if(ch=='-') f=-1,ch=getchar();
23     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
24 }
25 
26 int ecnt,fir[N],nxt[N<<1],to[N<<1],val[N<<1];
27 void add(int u,int v,int w) {
28     nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
29     if(u!=v) {
30         nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;
31     }
32 }
33 
34 db g[107][107];
35 int gauss(int n) {
36     For(i,1,n) {
37         int now=i;
38         For(j,i+1,n) if(g[j][i]>g[now][i]) now=j;
39         if(now!=i) For(j,i,n+1) swap(g[i][j],g[now][j]);    
40         if(!g[i][i]) return -1;    
41         db t=g[i][i];
42         For(j,i,n+1) g[i][j]/=t;
43         For(j,i+1,n) if(g[j][i]) {
44             db t=g[j][i];
45             For(k,i,n+1) g[j][k]-=t*g[i][k];
46         }
47     }
48     Rep(i,n,1) 
49         For(j,i+1,n) g[i][n+1]-=g[j][n+1]*g[i][j]; 
50     return 1;
51 }
52 
53 db solve(int pos) {
54     memset(g,0,sizeof(g));
55     For(x,1,n-1) {
56         for(int i=fir[x];i;i=nxt[i]) {
57             g[x][x]++;
58             int y=to[i];
59             if(val[i]&(1<<pos)) {
60                 g[x][y]++; g[x][n+1]++;
61             }
62             else g[x][y]--;
63         }
64     }
65     g[n][n]=1;
66     int rs=gauss(n);
67     if(rs==-1) return 0;
68     return g[1][n+1];
69 }
70 
71 int main() {
72 #ifdef DEBUG
73     freopen(".in","r",stdin);
74     freopen(".out","w",stdout);
75 #endif
76     read(n); read(m);
77     For(i,1,m) {
78         int x,y,z;
79         read(x); read(y); read(z);
80         add(x,y,z); mxw=max(mxw,z);
81     }
82     db ans=0;
83     For(i,0,29) {
84         if((1<<i)>mxw) break;
85         db pp=solve(i);
86         ans+=pp*(1<<i);
87     }
88     printf("%.3lf\n",ans);
89     return 0;
90 }
91 /*
92 2 2
93 1 1 2
94 1 2 3
95 
96 3 3
97 1 2 4
98 1 3 5
99 */
View Code

 

bzoj3036绿豆蛙的归宿

真正的大水题.

 1 //Achen
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<vector>
 7 #include<cstdio>
 8 #include<queue>
 9 #include<cmath>
10 #include<set>
11 #define For(i,a,b) for(int i=(a);i<=(b);i++)
12 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
13 typedef long long LL; 
14 typedef double db;
15 using namespace std;
16 const int N=200007;
17 int n,m;
18 
19 template<typename T> void read(T &x) {
20     char ch=getchar(); x=0; T f=1;
21     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
22     if(ch=='-') f=-1,ch=getchar();
23     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
24 }
25 
26 int ecnt,fir[N],nxt[N],to[N],val[N],out[N],vis[N];
27 void add(int u,int v,int w) {
28     nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w; out[u]++;
29 }
30 
31 db f[N];
32 void dfs(int x) {
33     if(vis[x]) return ;
34     vis[x]=1;
35     for(int i=fir[x];i;i=nxt[i]) {
36         int y=to[i];
37         dfs(y);
38         f[x]+=(f[y]+val[i]);
39     }
40     if(out[x]) f[x]=f[x]/(db)out[x];
41 }
42 
43 int main() {
44 #ifdef DEBUG
45     freopen(".in","r",stdin);
46     freopen(".out","w",stdout);
47 #endif
48     read(n); read(m);
49     For(i,1,m) {
50         int u,v,w;
51         read(u); read(v); read(w);
52         add(u,v,w);
53     }
54     dfs(1);
55     printf("%.2lf\n",f[1]);
56     return 0;
57 }
View Code

 

3566: [SHOI2014]概率充电器

f[x]表示x点冲到点的概率,如何转移都发现互相影响

那么考虑反着做,f[x]表示x点冲不上点的概率

g[x]表示只考虑以x为根的子树,x冲不上电的概率

p[x]表示x自己给自己冲上电的概率

q[x]表示x到父亲的边能用的概率

g[x]=(1-p[x])*∏(y is son of x)(g[y]+(1-g[y])*(1-p[y]));

一遍树dp求出g

对于根rt , f[rt]=g[rt]

从根往下依次计算每个点的f,相当于树dp换根,把父亲的f值除去我的贡献,父亲就变成了我的儿子.可以计算出我的f值

 1 //Achen
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<vector>
 7 #include<cstdio>
 8 #include<queue>
 9 #include<cmath>
10 #include<set>
11 #define For(i,a,b) for(int i=(a);i<=(b);i++)
12 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
13 const int N=1001000;
14 typedef long long LL; 
15 typedef double db;
16 using namespace std;
17 int n,m;
18 db p[N];
19 
20 template<typename T> void read(T &x) {
21     char ch=getchar(); x=0; T f=1;
22     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
23     if(ch=='-') f=-1,ch=getchar();
24     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
25 }
26 
27 int ecnt,fir[N],nxt[N<<1],to[N<<1];
28 db val[N<<1];
29 void add(int u,int v,db w) {
30     nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
31     nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;
32 }
33 
34 db f[N],g[N],ans;
35 void dfs1(int x,int fa) {
36     g[x]=(1.0-p[x]);
37     for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa) {
38         int y=to[i];
39         dfs1(y,x);
40         g[x]*=(g[y]+(1.0-g[y])*(1.0-val[i]));
41     }
42 }
43 
44 void dfs2(int x,int fa) {
45     ans+=(1.0-f[x]);
46     for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa) {
47         int y=to[i];
48         db tp=g[y]+(1.0-g[y])*(1.0-val[i]);
49         db ff=tp<1e-6?0:f[x]/tp;
50         f[y]=g[y]*(ff+(1.0-ff)*(1.0-val[i]));
51         dfs2(y,x);
52     }
53 }
54 
55 int main() {
56 #ifdef DEBUG
57     freopen(".in","r",stdin);
58     freopen(".out","w",stdout);
59 #endif
60     read(n);
61     For(i,1,n-1) {
62         int u,v; db w;
63         read(u); read(v); read(w);
64         w/=100.0;
65         add(u,v,w);
66     }
67     For(i,1,n) { read(p[i]); p[i]/=100.0; }
68     dfs1(1,0);
69     f[1]=g[1];
70     dfs2(1,0);
71     printf("%.6lf\n",ans);
72     return 0;
73 }
View Code

 

posted @ 2018-04-23 19:09  啊宸  阅读(223)  评论(0编辑  收藏  举报