zoukankan      html  css  js  c++  java
  • 高斯消元

    有方程组

    [egin{cases}k_{1,1}a_1+k_{1,2}a_2+……+k_{1,n}a_n=b_1\k_{2,1}a_1+k_{2,2}a_2+……+k_{2,n}a_n=b_2\……\k_{n,1}a_1+k_{n,2}a_2+……+k_{n,n}a_n=b_nend{cases} ]

    其中(k_i,b_i)已知,求(a_i)

    根据初中芝士,我们可以选择加减/代入消元,但是对于算法来说,我们要有一般性的方法

    一般来说,我们选择把主对角线全部消成(1),主对角线下的数全部消成(0)

    [egin{cases}1 k^{'}_{1,2} k^{'}_{1,3}=b^{'}_{1}\0 1 k^{'}_{2,3}=b^{'}_{2}\0 0 1=b^{'}_{3}end{cases} ]

    类似这样的,如果消不成上三角,那么说明原方程组无解

    我们每次选择一个绝对值最大的系数,先将该系数消成(1)

    用该项将其他式子的对应项直接消为(0),其他项对应减去(frac{a_{jnow}}{a_{inow}}*a_{iw})

    至于为什么选最大的,首先如果最大的为(0)或小于(eps),那么方程组无解,其次选择最大的可以降低精度误差

    对于(n)元方程组,显然需要消元(n)次,每次消元需要(n^2)复杂度,所以总复杂度(O(n^3))

    好像原理很简单,不过实现需要稍微脑补一下

    (upd:)个人觉得没讲明白,但是我太菜了好像想不到更细致的解释了……先康康代码吧

    #include<bits/stdc++.h>
    using namespace std;
    namespace red{
    #define int long long
    #define eps (1e-8)
    	inline int read()
    	{
    		int x=0;char ch,f=1;
    		for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
    		if(ch=='-') f=0,ch=getchar();
    		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    		return f?x:-x;
    	}
    	int n;
    	double a[110][110],ret[110];
    	inline void main()
    	{
    		n=read();
    		for(int i=1;i<=n;++i)
    		{
    			for(int j=1;j<=n+1;++j)
    			{
    				scanf("%lf",&a[i][j]);
    			}
    		}
    		for(int i=1;i<=n;++i)
    		{
    			int t=i;
    			for(int j=i+1;j<=n;++j)
    				if(fabs(a[j][i])>fabs(a[t][i])) t=j;
    			if(fabs(a[t][i])<eps)
    			{
    				puts("No Solution");
    				return;
    			}
    			if(t!=i) swap(a[i],a[t]);
    			double div=a[i][i];
    			for(int j=i;j<=n+1;++j) a[i][j]/=div;
    			for(int j=i+1;j<=n;++j)
    			{
    				div=a[j][i];
    				for(int k=i;k<=n+1;++k)
    					a[j][k]-=(a[i][k]*div);
    			}
    		}
    		ret[n]=a[n][n+1];
    		for(int i=n-1;i;--i)
    		{
    			ret[i]=a[i][n+1];
    			for(int j=i+1;j<=n;++j)
    				ret[i]-=(a[i][j]*ret[j]);
    		}
    		for(int i=1;i<=n;++i) printf("%.2lf
    ",ret[i]);
    	}
    }
    signed main()
    {
    	red::main();
    return 0;
    }
    

    高斯消元解图上期望(DP)

    bzoj1444: [Jsoi2009]有趣的游戏
    洛谷P3232[HNOI2013]游走

  • 相关阅读:
    nodepad++中的正则表达式匹配和替换操作。
    QT Creator配置环境和安装
    圣诞树小程序的制作
    C#编辑xml文件
    delegate里的Invoke和BeginInvoke
    记录RFID操作错误
    关于Panel隐藏横向滚动条
    随笔
    Java图形打印 上下对称三角星
    Centos 7.5安装 Redis 5.0.0
  • 原文地址:https://www.cnblogs.com/knife-rose/p/12025082.html
Copyright © 2011-2022 走看看