hdu 4579(稀疏矩阵消元(每行稀疏元连续))

本题目是典型的建立方程组用高斯消元法求解。

但是问题在于方程组有n个,未知数有n个,直接上模板会超时,那么手写个消元就可以了,对高斯消元每行的操作对于本题目都可以降到o(m)。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define rep(i,n) for(int i=0;i<(int)n;i++)
#define rep1(i,x,y) for(int i=x;i<=y;i++)
typedef long long ll;
typedef long long LL;

const int N = 50505;
double c[N][6];
double d[N][30];
int main()
{
    int n,m;
    while(scanf("%d %d",&n,&m)==2 && n+m){
       rep1(i,1,n) rep1(j,1,m) scanf("%lf",&c[i][j]);
       memset(d,0,sizeof(d));
       d[n][6]=1; d[n][29]=0;
       rep1(i,1,n-1){
           d[i][6] = 0;
           int sum =0; rep1(k,1,m) sum+=c[i][k];
           d[i][29] = 1;
           rep1(j,max(1,i-m),min(i+m,n))if(j!=i){
                double p;
                if(j<i) p=0.3*c[i][i-j]/(1+sum);
                if(j>i) p=0.7*c[i][j-i]/(1+sum);
                d[i][6+(j-i)]=-p; d[i][6]+=p;
           } 
       }
       rep1(i,1,n-1){
           int r = i; double tem=d[i][6];
           for(int j=1;i+j<=n&&j<=m;j++){
               if(fabs(d[i+j][6-j]) > fabs(tem)){
                   tem=d[i+j][6-j];  r=i+j;
               }
           }
           if(r!=i) {
               rep1(j,6,6+m+r-i) swap(d[i][j],d[r][j-(r-i)]);
               swap(d[i][29],d[r][29]);
           }
           for(int j=1;i+j<=n&&j<=m;j++)if(d[i+j][6-j]!=0){
               double t=d[i+j][6-j]/d[i][6];
               for(int k=6-j;k<=6+m;k++) d[i+j][k]-=t*d[i][k+j];
               d[i+j][29]-=d[i][29]*t;
           }
       }
       for(int i=n-1;i>=1;i--){
             for(int j=min(n,i+m);j>i;j--){ d[i][29]-=d[j][29]*d[i][j-i+6];  }
             d[i][29]=d[i][29]/d[i][6];
       }
       printf("%.2lf\n",d[1][29]);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值