zoukankan      html  css  js  c++  java
  • [bzoj3317]First Knight

    建立方程后直接高斯消元,再把0的区间找出来计算,就可以过(因为实际上这样的复杂度是5次的,且常数小)
    (当然这样的复杂度看上去并不太好,考虑优化)
    可以发现最后一行的概率都可以用上一行来表示,那么代入上一行的方程后,发现又可以再次代入,最后就求出了第一行

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int t,n,m,dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
     4 double f[2005][2005];
     5 int id(int x,int y){
     6     if ((x<1)||(y<1)||(x>n)||(y>m))return 0;
     7     return (x-1)*m+y;
     8 }
     9 double guess(){
    10     for(int ii=n;ii;ii--){
    11         for(int i=id(ii,1);i<=id(ii,m);i++){
    12             double s=abs(f[i][i]);
    13             for(int j=i+1;j<=id(ii,m);j++)s=max(s,abs(f[j][i]));
    14             for(int j=i;j<=id(ii,m);j++)
    15                 if (s==abs(f[j][i])){
    16                     s=f[j][i];
    17                     for(int k=id(ii-1,1);k<=id(ii,m);k++)swap(f[j][k],f[i][k]);
    18                     swap(f[j][id(n,m)+1],f[i][id(n,m)+1]);
    19                     break;
    20                 }
    21             for(int j=id(ii-1,1);j<=id(ii,m);j++)f[i][j]/=s;
    22             f[i][id(n,m)+1]/=s;
    23             for(int j=id(ii,1);j<=id(ii,m);j++){
    24                 if (j==i)continue;
    25                 s=f[j][i];
    26                 for(int k=id(ii-1,1);k<=id(ii,m);k++)f[j][k]-=f[i][k]*s;
    27                 f[j][id(n,m)+1]-=f[i][id(n,m)+1]*s;
    28             }
    29         }
    30         if (ii==1)return f[1][id(n,m)+1];
    31         for(int i=id(ii-1,1);i<=id(ii-1,m);i++)
    32             for(int j=id(ii,1);j<=id(ii,m);j++){
    33                 for(int k=id(ii-1,1);k<=id(ii-1,m);k++)f[i][k]-=f[i][j]*f[j][k];
    34                 f[i][id(n,m)+1]-=f[i][j]*f[j][id(n,m)+1];
    35             }
    36     }
    37 }
    38 int main(){
    39     while (scanf("%d%d",&n,&m)!=EOF){
    40         if ((!n)&&(!m))return 0;
    41         memset(f,0,sizeof(f));
    42         for(int i=1;i<=n;i++)
    43             for(int j=1;j<=m;j++)
    44                 f[id(i,j)][id(i,j)]=f[id(i,j)][id(n,m)+1]=-1;
    45         for(int k=0;k<4;k++)
    46             for(int i=1;i<=n;i++)
    47                 for(int j=1;j<=m;j++)
    48                     scanf("%lf",&f[id(i,j)][id(i+dx[k],j+dy[k])]);
    49         f[id(n,m)][id(n,m)+1]=0;
    50         printf("%.8f
    ",guess());
    51     }
    52 }
    View Code
  • 相关阅读:
    hdu 1823 Luck and Love 二维线段树
    UVA 12299 RMQ with Shifts 线段树
    HDU 4578 Transformation 线段树
    FZU 2105 Digits Count 线段树
    UVA 1513 Movie collection 树状数组
    UVA 1292 Strategic game 树形DP
    【ACM】hdu_zs2_1003_Problem C_201308031012
    qsort快速排序
    【ACM】nyoj_7_街区最短路径问题_201308051737
    【ACM】nyoj_540_奇怪的排序_201308050951
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11733830.html
Copyright © 2011-2022 走看看