• uva 542 France '98


    题意:题目只有一个case,有16个球队,给出名字,并且下面一个16*16的矩阵,p[i][j]是一个二位的整数,表示i球队打败j球队的概率,p[i][j]+p[j][i]=100,下面16行输出球队名字并且后面一个百分率是该球队获得总冠军的概率

    DP递推或者记忆化搜索都可以

    设dp[i][left][right]表示i这个球队在第left到第right球队里面得到冠军的概率,所以最后需要的是dp[i][1][16]。一个球队要在当面的阶段得到冠军必须在之前得到冠军

    所以mid=(left+right)/2;  

    i和j在[left,right]里面争夺冠军(例如i和j在1到16里面争夺冠军,也就是争夺总冠军),那么i和j必定是来自于两个分区的

    left<=i<=mid , 那么需要得到dp[i][left][mid],dp[j][mid+1][right] 

    mid+1<=i<=right,那么需要得到dp[i][mid+1][right] , dp[j][left][mid]

    具体看代码吧

    DP递推

    #include <cstdio>
    #include <cstring>
    double p[20][20],dp[20][20][20];
    char name[20][50];
    
    int main()
    {
        int N=16;
        for(int i=1; i<=N; i++) scanf("%s",name[i]);
        for(int i=1; i<=N; i++)
            for(int j=1; j<=N; j++)
            { scanf("%lf",&p[i][j]); p[i][j]/=100; }
    
        int len,left,right,mid,i,j;
    
        memset(dp,0,sizeof(dp));
        for(int i=1; i<=N; i++) dp[i][i][i]=1;
    
        for(len=2; len<=N; len*=2)
            for(left=1; left<=N; left+=len)
            {
                right=left+len-1; mid=(left+right)/2;
                for(i=left; i<=mid; i++)
                    for(j=mid+1; j<=right; j++)
                    {
                        dp[i][left][right]+=p[i][j]*dp[i][left][mid]*dp[j][mid+1][right];
                        dp[j][left][right]+=p[j][i]*dp[i][left][mid]*dp[j][mid+1][right];
                    }
            }
        for(i=1; i<=N; i++) printf("%-10s p=%.2f%%\n",name[i],dp[i][1][N]*100);
        return 0;
    }

    DO记忆化搜索

    #include <cstdio>
    #include <cstring>
    
    struct team
    {
        char name[110];
        int n;
    }a[20];
    double p[20][20];
    double dp[20][20][20];
    
    
    void dfs(int i ,int left ,int right)
    {
        if(dp[i][left][right]!=-1) return ;
    
        int mid=(left+right)/2;
        int l1,r1,l2,r2;
    
        if(i<=mid) {l1=left; r1=mid; l2=mid+1; r2=right;}
        else       {l1=mid+1; r1=right; l2=left; r2=mid;}
    
        dp[i][left][right]=0;
        for(int j=l2; j<=r2; j++)
        {
            dfs(i,l1,r1);  dfs(j,l2,r2);
            dp[i][left][right]+=p[i][j]*dp[i][l1][r1]*dp[j][l2][r2];
        }
    }
    
    int main()
    {
        int N=16;
        for(int i=1; i<=N; i++)
        { scanf("%s",a[i].name); a[i].n=i; }
    
        for(int i=1; i<=N; i++)  
            for(int j=1; j<=N; j++)  
            { scanf("%lf",&p[i][j]); p[i][j]/=100; }
    
        for(int i=1; i<=N; i++) 
            for(int j=1; j<=N; j++) 
                for(int k=1; k<=N; k++) 
                    dp[i][j][k]=-1;
        for(int i=1; i<=N; i++) dp[i][i][i]=1;
    
        int left=1,right=N,mid,l1,r1,l2,r2;
    
        mid=(left+right)/2;
        for(int i=left; i<=right; i++)
        {
            if(i<=mid) {l1=left; r1=mid; l2=mid+1; r2=right;}
            else       {l1=mid+1; r1=right; l2=left; r2=mid;}
    
            dp[i][left][right]=0.0;
            for(int j=l2; j<=r2; j++)
            {
                dfs(i,l1,r1);   dfs(j,l2,r2);
                dp[i][left][right]+=p[i][j]*dp[i][l1][r1]*dp[j][l2][r2];
            }
            printf("%-10s p=%.2f%%\n", a[i].name , dp[i][left][right]*100);
        }
    
        return 0;
    }
  • 相关阅读:
    phpStorm 安装配置
    node.js 模块之url和querystring模块
    node.js模块之util模块
    JAVA设计模式(09):结构型-代理模式(Proxy)
    VB.NET版机房收费系统---七仙女之系统登录
    Guava Collect
    win7 vs2010 安装cocos2d-x
    持久化API(JPA)系列(三)实体Bean的开发技术-建立与数据库的连接
    安卓kernel自主唤醒系统方法—设置alarm
    JSP导出Excel文件
  • 原文地址:https://www.cnblogs.com/scau20110726/p/2909435.html
Copyright © 2020-2023  润新知