高斯消元:

解$n$元一次方程组的通用方法,大部分时候用于解决没有明显转移顺序的dp。

考虑将方程组列成一个$n\times (n+1)$的矩阵$A$,然后依次枚举每一个未知数$j$(第$j$列):

  1. 从上往下找到第一个$i$,满足$i\geq j,A_{i,j}\neq 0$。
  2. 如果找不到则该方程组无解,退出。否则把第$i$行与第$j$行交换。
  3. 对于任意$k\neq j$,用第$j$行消第$k$行,使其满足$A_{k,j}=0$。

显然最后消出的是一个对角线矩阵(只在$A_{i,i}$处不为0),此时方程组的解$x_{i}=\frac{A_{i,n+1}}{A_{i,i}}$。

复杂度$O(n^{3})$。

#include<bits/stdc++.h>
#define maxn 505
#define maxm 500005
#define inf 0x7fffffff
#define ll long long
#define rint register int
#define debug(x) cerr<<#x<<": "<<x<<endl
#define fgx cerr<<"--------------"<<endl
#define dgx cerr<<"=============="<<endl

using namespace std;
int n; double A[maxn][maxn];

inline int read(){
    int x=0,f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}

inline bool Gauss(){
    for(int j=1;j<=n;j++){
        for(int i=j;i<=n;i++){
            if(A[i][j]==0) continue;
            for(int k=1;k<=n+1;k++) swap(A[i][k],A[j][k]); 
            break;
        }
        if(A[j][j]==0) return 0;
        for(int i=1;i<=n;i++){
            if(i==j || A[i][j]==0) continue;
            double x=A[i][j]/A[j][j];
            for(int k=1;k<=n+1;k++) A[i][k]-=A[j][k]*x;
        }
    }
    return 1;
}

int main(){
    n=read();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n+1;j++)
            A[i][j]=read();
    if(!Gauss()) printf("No Solution\n");
    else for(int i=1;i<=n;i++) printf("%.2lf\n",A[i][n+1]/A[i][i]);
    return 0;
}
高斯消元

相关文章:

  • 2022-01-14
  • 2022-01-02
  • 2021-06-05
  • 2021-07-09
  • 2022-12-23
  • 2021-04-10
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-01-09
  • 2021-11-22
  • 2021-06-25
  • 2022-12-23
  • 2021-08-09
  • 2022-12-23
  • 2022-02-19
相关资源
相似解决方案