zoukankan      html  css  js  c++  java
  • HDU4800 二维dp 状态转移很灵活

    【题意】:N种队伍,每两个队伍I,J之间PK, I 赢的概率是PK[I][J]

    M轮PK,双方开始各选一只队伍,若你打败了对手,你可以选择在下一次更换成他手上的队伍,假设你每次都选择最容易最终获胜的方法,求连续打赢M场概率的最大的概率。

    【分析】:

    dp[i][j]:表示用j号队员打败了第i个对手的最大的概率。

    昨天晚上一直W。

    dp很容易写错,下面是我的经验

    1、尽量要考虑第一层的边界(多是多个入口的题目要这样)

    2、下标一定要对

    3、dp定义数组一定不能过小,不然会越界出错

    4、初始化注意下标范围

    出错时检查:

    1、输入输出1、下标定义2、初始化的下标3、小数据4、状态方程的逻辑性是否正确

    我觉得这道题的巧妙在于,分析复杂度后你会发现是N*M的,但却有着三维的外衣

    for(int i=2;i<=N;i++){
         for(int j=0;j<M;j++){
          if (j==pk[i-1]){
             for(int k=0;k<M;k++){
               dp[i][j]=fmax(dp[i][j],dp[i-1][k]*p[j][pk[i]]);
             }
            }else {
               dp[i][j]=dp[i-1][j]*p[j][pk[i]];
          }
       }
    }

    那么最终ans=max(dp[N][i])枚举i即可

    【代码】:

     1 #include<iostream>
     2 #include<stdio.h>
     3 
     4 using namespace std;
     5 
     6 double dp[10005][125];
     7 double p[125][125];
     8 int pk[10005];
     9 
    10 int N,M;
    11 
    12 double fmax(double a,double b){
    13     if(a-b>0) return a;else return b;
    14 }
    15 int main(){
    16     //freopen("out.txt","w",stdout);
    17     while(~scanf("%d",&M)){
    18         M=(M)*(M-1)*(M-2)/6;
    19         for(int i=0;i<M;i++){
    20             for(int j=0;j<M;j++) scanf("%lf",&p[i][j]);
    21         }
    22         scanf("%d",&N);
    23         for(int i=1;i<=N;i++) scanf("%d",&pk[i]);
    24 
    25         for(int i=0;i<M;i++) dp[1][i]=p[i][pk[1]];
    26         for(int i=0;i<M;i++){
    27             for(int j=2;j<=N;j++) dp[j][i]=0.0;
    28         }
    29         for(int i=2;i<=N;i++){
    30             for(int j=0;j<M;j++){
    31                 if (j==pk[i-1]){
    32                     for(int k=0;k<M;k++){
    33                         dp[i][j]=fmax(dp[i][j],dp[i-1][k]*p[j][pk[i]]);
    34                     }
    35                 }else {
    36                     dp[i][j]=dp[i-1][j]*p[j][pk[i]];
    37                 }
    38             }
    39         }
    40 
    41         double ans=-1.0;
    42         for(int i=0;i<M;i++) ans=fmax(ans,dp[N][i]);
    43 
    44         printf("%lf
    ",ans);
    45 
    46     }
    47     return 0;
    48 }
    View Code
  • 相关阅读:
    个人技术博客(α)------javaweb的学习路程
    使用github客户端上传文件(瓜皮教程)
    软件工程实践 : 团队项目(第三次作业) 需求规格说明书
    软件工程实践 · 团队项目(第二次作业)
    软件工程实践:结对作业(第二次作业)
    软件工程实践:结对作业(第一次作业)
    软件工程实践 · 团队项目(第一次作业)
    班级连接
    软件工程 第二次作业(改)
    Shader Forge 刀光溶解
  • 原文地址:https://www.cnblogs.com/little-w/p/3768614.html
Copyright © 2011-2022 走看看