首页 > 其他 > 详细

[bzoj3317]First Knight

时间:2019-10-24 19:47:49      阅读:84      评论:0      收藏:0      [点我收藏+]

建立方程后直接高斯消元,再把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\n",guess());
51     }
52 }
View Code

 

[bzoj3317]First Knight

原文:https://www.cnblogs.com/PYWBKTDA/p/11733830.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!