【总览】

高斯消元基本思想是将方程式的系数和常数化为矩阵,通过将矩阵通过行变换成为阶梯状(三角形),然后从小往上逐一求解。

如:$3X_1 + 2X_2 + 1X_3 = 3$

  $              X_2 + 2X_3 = 1$

  $2X_1 + X_3 = 0$

化为矩阵为:--->----->----->

然后就可以通过最后一行直接求出$X_3 = ...$,将其带回第二行,算出$X_2$,同理算出$X_1$。

代码很好理解:

inline void gauss(){int i, j, k, l;for(i = 1; i <= n; i++){l = i;for(j = i + 1; j <= n; j++)if(fabs(matrix[j][i]) > fabs(matrix[l][i])) l = j;if(l != i) for(j = i; j <= n + 1; j++)swap(matrix[i][j], matrix[l][j]);for(j = i + 1; j <= n; j++){double tmp = matrix[j][i] / matrix[i][i];for(k = i; k <= n + 1; k++)matrix[j][k] -= matrix[i][k] * tmp;}}for(i = n; i >= 1; i--){double t = matrix[i][n + 1];for(j = n; j > i; j--)t -= ans[j] * matrix[i][j];ans[i] = t / matrix[i][i];}
}

高斯消元最常应用在  期望DP  中。下面是几道例题。

“期望dp讲解及例题”

【BZOJ1013】球形空间产生器sphere

由给出的$n + 1$个坐标,可以列出 $n$个方程,剩下的模板。

【CODE】

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;const int N = 20;
double matrix[N][N], last[N], t, ans[N];
int n;inline int read(){int i = 0, f = 1; char ch = getchar();for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());if(ch == '-') f = -1, ch = getchar();for(; ch >= '0' && ch <= '9'; ch = getchar())i = (i << 3) + (i << 1) + (ch -'0');return i * f;
}inline void wr(int x){if(x < 0) putchar('-'), x = -x;if(x > 9) wr(x / 10);putchar(x % 10 + '0');
}inline void gauss(){int i, j, l, k;for(i = 1; i <= n; i++){l = i;for(j = i + 1; j <= n; j++) if(fabs(matrix[j][i]) > fabs(matrix[l][i])) l = j;if(l != i) for(j = i; j <= n + 1; j++)swap(matrix[i][j], matrix[l][j]);for(j = i + 1; j <= n; j++){double tmp = matrix[j][i] / matrix[i][i];for(k = i; k <= n + 1; k++) matrix[j][k] -= matrix[i][k] * tmp;}}for(i = n; i >= 1; i--){double tmp = matrix[i][n + 1];for(j = n; j > i; j--)tmp -= ans[j] * matrix[i][j];ans[i] = tmp / matrix[i][i];}
}int main(){n = read();for(int i = 1; i <= n; i++) scanf("%lf", &last[i]);for(int i = 1; i <= n; i++){t = 0;for(int j = 1; j <= n; j++){double tmp; scanf("%lf", &tmp);matrix[i][j] = 2 * (tmp - last[j]);t += tmp * tmp - last[j] * last[j];last[j] = tmp;}matrix[i][n + 1] = t;}gauss();for(int i = 1; i <= n; i++){if(i < n) printf("%.3lf ", ans[i]);else printf("%.3lf\n", ans[i]);}return 0;
}

【BZOJ3143】游走

  因为要求期望的最小值,那么走的次数多的边肯定要让花费(编号)尽可能小,所以可以先求出从每个点出发次数的期望值$E_i$,那么对于一条边而言,走这条边的期望次数就是$E_i / degree[i] + E_j / degree[j]$,只要排一遍序就好。

  求点的期望:$E_i = \sum (E_{son[i]} / degree[i])$

【code】

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<vector>
#define eps 1e-10
using namespace std;const int N = 600;
double matrix[N][N], ans[N], ret;
int n, m, num, degree[N];
int st[500000], ed[500000];
double gg[500000];inline void addEdge(const int &u, const int &v){degree[u]++;degree[v]++;st[++num] = u, ed[num] = v;
}inline int read(){int i = 0, f = 1; char ch = getchar();for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());if(ch == '-') f = -1, ch = getchar();for(; ch >= '0' && ch <= '9'; ch = getchar())i = (i << 3) + (i << 1) + (ch -'0');return i * f;
}inline void gauss(){int i, j, l, k;for(i = 1; i <= n; i++){l = i;for(j = i + 1; j <= n; j++) if(fabs(matrix[j][i]) > fabs(matrix[l][i])) l = j;if(l != i) for(j = i; j <= n + 1; j++)swap(matrix[i][j], matrix[l][j]);for(j = i + 1; j <= n; j++){double tmp = matrix[j][i] / matrix[i][i];for(k = i; k <= n + 1; k++) matrix[j][k] -= matrix[i][k] * tmp;}}for(i = n; i >= 1; i--){double tmp = matrix[i][n + 1];for(j = n; j > i; j--)tmp -= ans[j] * matrix[i][j];ans[i] = tmp / matrix[i][i];}
}inline bool cmp (double a, double b){return a > b;
}int main(){n = read(), m = read();for(int i = 1; i <= m; i++){int u = read(), v = read();addEdge(u, v);}int i, j;for(i = 1; i <= m; i++){matrix[st[i]][ed[i]] += 1.0 /degree[ed[i]];matrix[ed[i]][st[i]] += 1.0 /degree[st[i]];}for(i = 1; i <= n; i++) matrix[n][i] = 0;  for(i = 1; i <= n; i++) matrix[i][i] = -1.0;matrix[1][n + 1] = -1.0;gauss();for(i = 1; i <= m; i++)gg[i] = ans[st[i]] / degree[st[i]] + ans[ed[i]] / degree[ed[i]];sort(gg + 1, gg + m + 1, cmp);for(i = 1; i <= m; i++) ret += gg[i] * i;printf("%.3f\n", ret);return 0;
}

【bzoj2337】XOR和路径

  学到了!看见求异或和$----->$按位计算:即一位一位的计算答案每一位上为1的期望值,这样就可以轻松统计出答案。

  每一位都要重新构造矩阵求期望,设$a[i]$表示从$i$到$n$的路径异或和(这一位)为$1$的期望概率(总是≤$1$)

  对于当前第$i + 1$位,若$(dis >> i) \& 1$(这一位为1),那么要异或和为$1$,要求他从关联点异或和为$0$转移来,

  同理,若这一位为$0$,要求从$1$转移来。即:$$a[i] = \sum a[son[i]](dis这一位为0) / degree[i]  + \sum a[son[i]](dis这一位为1) / degree[i]$$。

【code】

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cmath>
using namespace std;const int N = 105, M = 10005;
int n, m;
int ecnt, st[M << 1], ed[M << 1], len[M << 1], degree[N];
double matrix[N][N], ans[N], ret;inline void addEdge(const int &u, const int &v, const int &l){st[++ecnt] = u, ed[ecnt] = v, len[ecnt] = l; degree[u]++;if(u != v) st[++ecnt] = v, ed[ecnt] = u, len[ecnt] = l, degree[v]++;
}inline void gauss(){int i, j, k, l;for(i = 1; i <= n; i++){l = i;for(j = i + 1; j <= n; j++)if(fabs(matrix[j][i]) > fabs(matrix[l][i])) l = j;if(l != i) for(j = i; j <= n + 1; j++)swap(matrix[i][j], matrix[l][j]);for(j = i + 1; j <= n; j++){double tmp = matrix[j][i] / matrix[i][i];for(k = i; k <= n + 1; k++)matrix[j][k] -= matrix[i][k] * tmp;}}for(i = n; i >= 1; i--){double t = matrix[i][n + 1];for(j = n; j > i; j--)t -= ans[j] * matrix[i][j];ans[i] = t / matrix[i][i];}
}int main(){scanf("%d%d", &n, &m);int i, j, k;for(i = 1; i <= m; i++){int u, v, w; scanf("%d%d%d", &u, &v, &w);addEdge(u, v, w);}for(i = 0; i <= 30; i++){memset(matrix, 0, sizeof matrix);memset(ans, 0, sizeof ans);for(j = 1; j <= n; j++) matrix[j][j] = 1;for(j = 1; j <= ecnt; j++){int l = len[j], u = st[j], v = ed[j];if(u == n) continue;if((l >> i) & 1){matrix[u][v] += 1.0 / degree[u];matrix[u][n + 1] += 1.0 / degree[u];}else matrix[u][v] -= 1.0 / degree[u];}gauss();ret += ans[1] * (1 << i);}printf("%.3f\n", ret);return 0;
}

转载于:https://www.cnblogs.com/CzYoL/p/7226719.html

【高斯消元】兼 【期望dp】例题相关推荐

  1. P6030-[SDOI2012]走迷宫【高斯消元,tarjan,期望dp】

    正题 题面链接:https://www.luogu.com.cn/problem/P6030 题目大意 nnn个点的一张有向图,求起点到终点的期望步数.保证每个强连通分量大小不超过100100100. ...

  2. HDU4870_Rating_双号从零单排_高斯消元求期望

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4870 原题: Rating Time Limit: 10000/5000 MS (Java/Other ...

  3. 【HDU - 6185】Covering(矩阵快速幂优化二维dp,高斯消元,轮廓线dp打表)

    题干: Bob's school has a big playground, boys and girls always play games here after school. To protec ...

  4. BZOJ 3270: 博物馆 1778: 驱逐猪猡 【概率DP+高斯消元】

    题目描述: 中文题面,不多解释.1778传送门 3270 传送门 (博物馆)题目分析: 也许很多人做概率题的时候都有种虚幻感..感觉莫名其妙就得出一个期望.概率,一知半解... 所以我在这里仔细地剖析 ...

  5. BZOJ 3143: [Hnoi2013]游走 高斯消元 期望

    3143: [Hnoi2013]游走 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 3463  Solved: 1535 [Submit][Stat ...

  6. BZOJ3270 博物館 概率DP 高斯消元

    BZOJ3270 博物館 概率DP 高斯消元 @(XSY)[概率DP, 高斯消元] Description 有一天Petya和他的朋友Vasya在进行他们众多旅行中的一次旅行,他们决定去参观一座城堡博 ...

  7. 【4.7 高斯消元详解】

    更好的阅读体验 \color{red}{更好的阅读体验} 更好的阅读体验 目录 4.7 高斯消元 4.7.1 高斯消元解线性方程组 4.7.2 高斯消元解异或线性方程组 4.7 高斯消元 概念 利用初 ...

  8. LightOJ 1151 Snakes and Ladders (期望DP + 高斯消元)

    Description 'Snakes and Ladders' or 'Shap-Ludu' is a game commonly played in Bangladesh. The game is ...

  9. 【YBT2023寒假Day3 A】千与千寻(期望DP)(高斯消元)

    千与千寻 题目链接:YBT2023寒假Day3 A 题目大意 一个 n*m 的平面,你要从 (0,0) 走到 (x,y),你等概率的向上或向右走,然后当你走到 (n-1,i) 再往右走,就是 (0,i ...

最新文章

  1. 清华旷视:让VGG再次伟大!
  2. Linux之终端命令格式的组成
  3. 约瑟夫生死环游戏c语言程序,使用C++实现的约瑟夫生死游戏
  4. Bootstrap 按钮组
  5. 如何把一些不同类型的数据混合存入一片内存中_如何从技术上增强以太坊的隐私性?...
  6. SAP UI5函数节流(Throttle)的一个最简单的例子
  7. js 时间戳转换成时间_JavaScript 时间戳转成日期格式
  8. 写一个函数的程序,判断是否是浮点数
  9. 简短—揭开数学学科对于计算机应用的神秘面纱
  10. 【github系列】github创建tag
  11. 配置系列:(事物管理)ssm中applicationContext-transaction.xml的简单配置
  12. 在Java环境下怎么打开_Java环境配置及在Dos命令下运行Java程序
  13. 本科毕设论文查重方法(重点介绍笔杆网站)
  14. wav转mp3格式转换器哪个好
  15. 商城APP开发关键板块
  16. linux怎么设置raid,如何在Linux中配置RAID-教程
  17. Java知识点复习:Day14
  18. 智慧海洋task04 利用数据进行建模并调参
  19. 台式电脑上没有显示计算机怎么办,电脑显示器无视频输入怎么办
  20. python pip 豆瓣镜像

热门文章

  1. TCP/UDP编程中的问题汇总
  2. 关于mysql的表名/字段名/字段值是否区分大小写的问题
  3. Yii中缓存依赖的处理
  4. Linux查看进程和终止进程的技巧
  5. 浅谈FIle协议与Http协议及区别
  6. Coursera在线学习---第十节.大规模机器学习(Large Scale Machine Learning)
  7. Spore是一个平台,就知道没那么简单
  8. 初步学习“C#枚举”
  9. SQL server 200 安装问题!
  10. 【Linux 内核 内存管理】RCU 机制 ① ( RCU 机制简介 | RCU 机制的优势与弊端 | RCU 机制的链表应用场景 )