【高斯消元】兼 【期望dp】例题
【总览】
高斯消元基本思想是将方程式的系数和常数化为矩阵,通过将矩阵通过行变换成为阶梯状(三角形),然后从小往上逐一求解。
如:$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】例题相关推荐
- P6030-[SDOI2012]走迷宫【高斯消元,tarjan,期望dp】
正题 题面链接:https://www.luogu.com.cn/problem/P6030 题目大意 nnn个点的一张有向图,求起点到终点的期望步数.保证每个强连通分量大小不超过100100100. ...
- HDU4870_Rating_双号从零单排_高斯消元求期望
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4870 原题: Rating Time Limit: 10000/5000 MS (Java/Other ...
- 【HDU - 6185】Covering(矩阵快速幂优化二维dp,高斯消元,轮廓线dp打表)
题干: Bob's school has a big playground, boys and girls always play games here after school. To protec ...
- BZOJ 3270: 博物馆 1778: 驱逐猪猡 【概率DP+高斯消元】
题目描述: 中文题面,不多解释.1778传送门 3270 传送门 (博物馆)题目分析: 也许很多人做概率题的时候都有种虚幻感..感觉莫名其妙就得出一个期望.概率,一知半解... 所以我在这里仔细地剖析 ...
- BZOJ 3143: [Hnoi2013]游走 高斯消元 期望
3143: [Hnoi2013]游走 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 3463 Solved: 1535 [Submit][Stat ...
- BZOJ3270 博物館 概率DP 高斯消元
BZOJ3270 博物館 概率DP 高斯消元 @(XSY)[概率DP, 高斯消元] Description 有一天Petya和他的朋友Vasya在进行他们众多旅行中的一次旅行,他们决定去参观一座城堡博 ...
- 【4.7 高斯消元详解】
更好的阅读体验 \color{red}{更好的阅读体验} 更好的阅读体验 目录 4.7 高斯消元 4.7.1 高斯消元解线性方程组 4.7.2 高斯消元解异或线性方程组 4.7 高斯消元 概念 利用初 ...
- LightOJ 1151 Snakes and Ladders (期望DP + 高斯消元)
Description 'Snakes and Ladders' or 'Shap-Ludu' is a game commonly played in Bangladesh. The game is ...
- 【YBT2023寒假Day3 A】千与千寻(期望DP)(高斯消元)
千与千寻 题目链接:YBT2023寒假Day3 A 题目大意 一个 n*m 的平面,你要从 (0,0) 走到 (x,y),你等概率的向上或向右走,然后当你走到 (n-1,i) 再往右走,就是 (0,i ...
最新文章
- 清华旷视:让VGG再次伟大!
- Linux之终端命令格式的组成
- 约瑟夫生死环游戏c语言程序,使用C++实现的约瑟夫生死游戏
- Bootstrap 按钮组
- 如何把一些不同类型的数据混合存入一片内存中_如何从技术上增强以太坊的隐私性?...
- SAP UI5函数节流(Throttle)的一个最简单的例子
- js 时间戳转换成时间_JavaScript 时间戳转成日期格式
- 写一个函数的程序,判断是否是浮点数
- 简短—揭开数学学科对于计算机应用的神秘面纱
- 【github系列】github创建tag
- 配置系列:(事物管理)ssm中applicationContext-transaction.xml的简单配置
- 在Java环境下怎么打开_Java环境配置及在Dos命令下运行Java程序
- 本科毕设论文查重方法(重点介绍笔杆网站)
- wav转mp3格式转换器哪个好
- 商城APP开发关键板块
- linux怎么设置raid,如何在Linux中配置RAID-教程
- Java知识点复习:Day14
- 智慧海洋task04 利用数据进行建模并调参
- 台式电脑上没有显示计算机怎么办,电脑显示器无视频输入怎么办
- python pip 豆瓣镜像
热门文章
- TCP/UDP编程中的问题汇总
- 关于mysql的表名/字段名/字段值是否区分大小写的问题
- Yii中缓存依赖的处理
- Linux查看进程和终止进程的技巧
- 浅谈FIle协议与Http协议及区别
- Coursera在线学习---第十节.大规模机器学习(Large Scale Machine Learning)
- Spore是一个平台,就知道没那么简单
- 初步学习“C#枚举”
- SQL server 200 安装问题!
- 【Linux 内核 内存管理】RCU 机制 ① ( RCU 机制简介 | RCU 机制的优势与弊端 | RCU 机制的链表应用场景 )