zoukankan      html  css  js  c++  java
  • 水题乱刷

    【poj2960】 Collecting Bugs

    http://poj.org/problem?id=2096 (题目链接)

    题意

      有一个程序,其中有s个子结构,每个子结构出bug的概率相等。bug总共分成n类,每种bug出现的概率相等。每天找出一个bug,求所有子结构都出现bug并且每种bug都出现过所需要的期望天数。

    Solution

      终于领会了期望dp的一点点。。。

    细节

      %.4lf用G++交会Wa。。

    代码

    // poj2096
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #define LL long long
    #define inf 1<<30
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
     
    const int maxn=1010;
    double f[maxn][maxn];
    int n,m;
     
    int main() {
        scanf("%d%d",&n,&m);
        f[n][m]=0;
        for (int i=n;i>=0;i--)
            for (int j=m;j>=0;j--) {
                if (i+1<=n) f[i][j]+=f[i+1][j]*(1-(double)i/n)*(double)j/m;
                if (j+1<=m) f[i][j]+=f[i][j+1]*(1-(double)j/m)*(double)i/n;
                if (i+1<=n && j+1<=m) f[i][j]+=f[i+1][j+1]*(1-(double)i/n)*(1-(double)j/m);
                if (i!=n || j!=m) f[i][j]=(f[i][j]+1)/(1-(double)i/n*(double)j/m);
            }
        printf("%.4lf",f[0][0]);
        return 0;
    }
    

    【poj3744】 Scout YYF I

    http://poj.org/problem?id=3744 (题目链接)

    题意

      给出n个雷,分别在 a[1]...a[n] ,走一步概率为 p ,走两步概率为 1-p ,一开始在 1 号位置,问安全到达终点的概率。

    Solution

      很显然的dp:f[i]=p*f[i-1]+(1-p)*f[i-2]。考虑a[i]位置上有雷,那么安全通过的概率也就是到达f[a[i]+1]的概率为:f[a[i]-1]*(1-p)。

      因为a[i]很大,所以要分段用矩阵快速幂。

    细节

      代码能力下降的厉害。。。莫名Wa了的可以去看看Discuss,好坑。。

    代码

    // poj3744
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define inf 1<<30
    #define eps 1e-8
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
     
    double tmp[2][2],f[2][2],t[2][2],p;
    int a[20],n;
     
    void power(int k) {
        t[0][0]=p,t[0][1]=1,t[1][0]=1-p,t[1][1]=0;
        while (k) {
            if (k&1) {
                for (int i=0;i<=1;i++)
                    for (int j=0;j<=1;j++) {
                        tmp[i][j]=0;
                        for (int k=0;k<=1;k++) tmp[i][j]+=f[i][k]*t[k][j];
                    }
                memcpy(f,tmp,sizeof(f));
            }
            k>>=1;
            for (int i=0;i<=1;i++)
                for (int j=0;j<=1;j++) {
                    tmp[i][j]=0;
                    for (int k=0;k<=1;k++) tmp[i][j]+=t[i][k]*t[k][j];
                }
            memcpy(t,tmp,sizeof(t));
        }
    }
    int main() {
        while (scanf("%d%lf",&n,&p)!=EOF) {
            for (int i=1;i<=n;i++) scanf("%d",&a[i]);
            sort(a+1,a+1+n);a[0]=0;
            f[1][1]=1;
            for (int i=1;i<=n;i++) {
                f[1][0]=f[1][1]*p;
                f[0][1]=f[1][0]*p+f[1][1]*(1-p);
                f[0][0]=f[0][1]*p+f[1][0]*(1-p);
                if (a[i]-a[i-1]==1) {f[1][1]=0;break;}
                else if (a[i]-a[i-1]==2) f[1][1]=f[1][1]*(1-p);
                else if (a[i]-a[i-1]==3) f[1][1]=f[1][0]*(1-p);
                else if (a[i]-a[i-1]==4) f[1][1]=f[0][1]*(1-p);
                else power(a[i]-a[i-1]-5),f[1][1]=(1-p)*f[0][0];
            }
            if (fabs(f[1][1])<eps) puts("0.0000000");
            else printf("%.7lf
    ",f[1][1]);
        }
        return 0;
    }
    

    【codeforces 148D】 Bag of mice

    http://codeforces.com/problemset/problem/148/D (题目链接)

    题意

      包中有w个白鼠,b个黑鼠。公主和龙轮流画老鼠,公主先画,谁先画到白鼠谁就赢。龙每画完一只老鼠,就会有另一只老鼠从包中跑出来。每只老鼠被画到以及跑出的概率相等,问公主获胜的概率。

    Solution

      令${f_{0/1,i,j}}$表示此时公主/龙选,包中还剩i只白鼠,j只黑鼠,公主赢的概率。那么转移很显然:

    $${f_{0,i,j}=frac{i}{i+j}+frac{j}{i+j}*f_{1,i,j-1}}$$

    $${f_{1,i,j}=frac{j}{i+j}*(frac{i}{i+j-1}*f_{0,i-1,j-1}+frac{j}{i+j-1}*f_{0,i,j-2})}$$

    细节

      一个加号没打,看半天没看出来。。

    代码

    // codeforces148D
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define inf 1<<30
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
     
    const int maxn=1010;
    double f[2][maxn][maxn];
    int n,m;
     
    int main() {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++) f[0][i][0]=1;
        for (int i=1;i<=n;i++)
            for (int j=1;j<=m;j++) {
                f[0][i][j]=(double)(i+j*f[1][i][j-1])/(i+j);
                f[1][i][j]=(double)(i*f[0][i-1][j-1])/(i+j-1);
                if (j>1) f[1][i][j]+=(double)((j-1)*f[0][i][j-2])/(i+j-1);
                f[1][i][j]*=(double)j/(i+j);
            }
        printf("%.9lf",f[0][n][m]);
        return 0;
    }
    

    【bzoj1415】 Noi2005—聪聪和可可

    http://www.lydsy.com/JudgeOnline/problem.php?id=1415 (题目链接)

    题意

      一张图,聪聪想吃可可。每单位时间聪聪可以先移动两次;可可后移动一次或停在原地,它们的概率相等。问聪聪吃到可可的期望时间。

    Solution

      先bfs跑出两点间的最短距离。然后记忆化搜索就可以了,很水。。

    代码

    // bzoj1415
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #define LL long long
    #define inf 1<<30
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
     
    const int maxn=1010;
    struct edge {int to,next;}e[maxn<<1];
    int head[maxn],r[maxn],S,T,n,m,cnt;
    int dis[maxn][maxn],vis[maxn][maxn];
    double f[maxn][maxn];
     
    void link(int u,int v) {
        e[++cnt]=(edge){v,head[u]};head[u]=cnt;
        e[++cnt]=(edge){u,head[v]};head[v]=cnt;
    }
    void bfs(int s,int *d) {
        queue<int> q;q.push(s);
        while (!q.empty()) {
            int x=q.front();q.pop();
            for (int i=head[x];i;i=e[i].next)
                if (!d[e[i].to] && e[i].to!=s) d[e[i].to]=d[x]+1,q.push(e[i].to);
        }
    }
    double dfs(int s,int t) {
        if (vis[s][t]) return f[s][t];
        if (dis[s][t]==0) return 0;
        if (dis[s][t]<=2) return 1;
        vis[s][t]=f[s][t]=1;
        int k=inf,tmp=s;
        for (int i=head[tmp];i;i=e[i].next)
            if (dis[t][e[i].to]<dis[tmp][t] && e[i].to<k) k=e[i].to;
        tmp=k;k=inf;
        for (int i=head[tmp];i;i=e[i].next)
            if (dis[t][e[i].to]<dis[tmp][t] && e[i].to<k) k=e[i].to;
        tmp=k;
        for (int i=head[t];i;i=e[i].next)
            f[s][t]+=(double)1/(r[t]+1)*dfs(tmp,e[i].to);
        f[s][t]+=(double)1/(r[t]+1)*dfs(tmp,t);
        return f[s][t];
    }
    int main() {
        scanf("%d%d",&n,&m);
        scanf("%d%d",&S,&T);
        for (int u,v,i=1;i<=m;i++) {
            scanf("%d%d",&u,&v);
            link(u,v);r[u]++;r[v]++;
        }
        for (int i=1;i<=n;i++) bfs(i,dis[i]);
        printf("%.3lf",dfs(S,T));
        return 0;
    }
    

    【codeforces 442B】 Andrey and Problem

    http://codeforces.com/problemset/problem/442/B (题目链接)

    题意

      n个人,每个人有p[i]的概率出一道题。问如何选择其中s个人使得这些人正好只出1道题的概率最大。

    Solution

      很显然的概率dp,过了样例即可AC。。话说我为什么要刷B题→_→

    代码

    // codeforces442B
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define inf 1<<30
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
     
    const int maxn=200;
    double f[maxn][maxn],p[maxn][maxn],a[maxn];
    int n;
     
    int main() {
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%lf",&a[i]);
        for (int i=1;i<=n;i++) {
            p[i-1][0]=1;
            for (int j=1;j<=i;j++) {
                if (f[i-1][j]<f[i-1][j-1]*(1-a[i])+p[i-1][j-1]*a[i]) {
                    f[i][j]=f[i-1][j-1]*(1-a[i])+p[i-1][j-1]*a[i];
                    p[i][j]=p[i-1][j-1]*(1-a[i]);
                }
                else f[i][j]=f[i-1][j],p[i][j]=p[i-1][j];
            }
        }
        double ans=0;
        for (int i=1;i<=n;i++) ans=max(ans,f[n][i]);
        printf("%.12lf",ans);
        return 0;
    }
    

    【poj3071】 Football

    http://poj.org/problem?id=3071 (题目链接)

    题意

      ${2^n}$个队伍打淘汰赛,输的被淘汰。第1个队打第2个队,第3个队打第4个队······给出第i个队伍打赢第j个队伍的概率p[i][j],求哪只队伍获得冠军的可能性最大

    Solution

      很简单,想到一个dp方程:${f_{i,j}}$表示第i轮,j胜出的概率。转移很显然:

    $${f_{i,j}=f_{i-1,j}×f_{i-1,k}×p_{j,k}}$$

    代码

    // poj3071
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define inf 1<<30
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
     
    int bin[20],n,m;
    double f[1000][1000],p[1000][1000];
     
    int main() {
        bin[0]=1;for (int i=1;i<=10;i++) bin[i]=bin[i-1]<<1;
        while (scanf("%d",&n) && n>0) {
            int m=1<<n;
            for (int i=1;i<=m;i++)
                for (int j=1;j<=m;j++) scanf("%lf",&p[i][j]);
            for (int i=1;i<=m;i++) f[0][i]=1;
            for (int i=1;i<=n;i++)
                for (int j=1;j<=m;j++) {
                    int s=(j-1)/bin[i-1]+1;
                    f[i][j]=0;
                    if (s&1) {
                        for (int k=s*bin[i-1]+1;k<=(s+1)*bin[i-1];k++)
                            f[i][j]+=f[i-1][j]*f[i-1][k]*p[j][k];
                    }
                    else {
                        for (int k=(s-2)*bin[i-1]+1;k<=(s-1)*bin[i-1];k++)
                            f[i][j]+=f[i-1][j]*f[i-1][k]*p[j][k];
                    }
                }
            int ans=1;
            for (int i=2;i<=m;i++) if (f[n][ans]<f[n][i]) ans=i;
            printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    Installing — pylibmc 1.2.3 documentation
    Python-memcached的基本使用
    kindeditor在sae上传文件修改,适合php
    Kindeditor+web.py+SAE Storage 实现文件上传
    使用sae定时执行Python脚本
    Ueditor文本编辑器(新浪SAE平台版本)
    NicEdit
    Lind.DDD.LindMQ的一些想法
    Redis学习笔记~关于空间换时间的查询案例
    微信扫码支付~官方DEMO的坑~参数不能自定义
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/6552584.html
Copyright © 2011-2022 走看看