POJ1487 Single-Player Games 高斯消元
欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - POJ1487
题解概括
给出多个树形结构,由小写字母和数字表示,每个小写字母表示一棵小树。现在,以a为根节点,构建一棵大树,树可能是无限的。现在,一个人从树根往叶子走,直到无法走为止,得到该叶子结点上数值所表示的相应分数,人在分叉的地方走每条路的概率是一样的,求得分期望。
题解
首先通过关系建立方程组。
这个貌似很麻烦,但是很暴力,有码量没有难度。
然后高斯消元解方程。
要注意精度的问题。
解的时候要标记自由元。
也有点麻烦。
具体的看代码吧。
代码
- #include <cstring>
- #include <algorithm>
- #include <cstdio>
- #include <cmath>
- #include <cstdlib>
- using namespace std;
- typedef long double LD;
- const LD Eps=1e-8;
- const int N=30;
- int n,Case=0,now,pos[N];
- char str[300];
- bool free_x[N];
- LD a[N][N],x[N];
- void GetLn(){
- while (getchar()!='\n');
- }
- int Match_Pracket(int now){//now为当前要匹配的左括号位置。
- int len=strlen(str+1),p=0;
- for (int i=now;i<=len;i++){
- if (str[i]=='(')
- p++;
- if (str[i]==')')
- p--;
- if (!p)
- return i;
- }
- return -1;
- }
- bool Is_Num_Part(char ch){
- return ch=='-'||('0'<=ch&&ch<='9');
- }
- int GetNum(int now,int &Next){//now为当前要计算的数字的最左位置,Next返回跳过数字后的位置。
- int len=strlen(str+1),f=1,x=0;
- if (str[now]=='-')
- f=-1;
- else
- x=str[now]-'0';
- while (Is_Num_Part(str[++now]))
- x=x*10+str[now]-'0';
- Next=now;
- return x*f;
- }
- void dfs(int L,int R,LD p){
- if (L>R)
- return;
- int tot=0,i;
- for (i=L;i<=R;){
- if (Is_Num_Part(str[i])){
- int j,v=GetNum(i,j);
- i=j,tot++;
- continue;
- }
- if (str[i]=='('){
- i=Match_Pracket(i)+1;
- tot++;
- continue;
- }
- if ('a'<=str[i]&&str[i]<='z'){
- i++,tot++;
- continue;
- }
- i++;
- }
- p=p/tot;
- for (int i=L;i<=R;){
- if (Is_Num_Part(str[i])){
- int j,v=GetNum(i,j);
- i=j,a[now][n]-=p*v;
- continue;
- }
- if (str[i]=='('){
- int j=Match_Pracket(i);
- dfs(i+1,j-1,p);
- i=j+1;
- continue;
- }
- if ('a'<=str[i]&&str[i]<='z')
- a[now][str[i]-'a']+=p;
- i++;
- }
- }
- int Gauss(){
- memset(free_x,0,sizeof free_x);
- memset(pos,0,sizeof pos);
- int k,c;
- for (k=c=0;k<n&&c<n;k++,c++){
- int Mk=k;
- for (int i=k+1;i<n;i++)
- if (fabs(a[Mk][c])<fabs(a[i][c]))
- Mk=i;
- if (Mk!=k)
- for (int i=c;i<=n;i++)
- swap(a[Mk][i],a[k][i]);
- if (fabs(a[k][c])<Eps){
- k--;
- free_x[c]=1;
- continue;
- }
- pos[k]=c;
- for (int i=k+1;i<n;i++)
- if (fabs(a[i][c])>Eps){
- for (int j=n;j>=c;j--)
- a[i][j]=a[i][j]-a[k][j]/a[k][c]*a[i][c];
- a[i][c]=0;
- }
- }
- for (int i=k;i<n;i++)
- if (fabs(a[i][n])>Eps)
- return -1;
- memset(x,0,sizeof x);
- for (int i=k-1;i>=0;i--){
- if (free_x[pos[i]])
- continue;
- LD tmp=a[i][n];
- for (int j=pos[i]+1;j<n;j++){
- if (fabs(a[i][j])<Eps)
- continue;
- if (free_x[j]){
- free_x[pos[i]]=1;
- break;
- }
- tmp-=a[i][j]*x[j];
- }
- if (!free_x[pos[i]])
- x[pos[i]]=tmp/a[i][pos[i]];
- if (fabs(x[pos[i]])<Eps)
- x[pos[i]]=0;
- }
- return 0;
- }
- int main(){
- while (~scanf("%d",&n)&&n){
- GetLn();
- memset(a,0,sizeof a);
- for (now=0;now<n;now++){
- a[now][now]-=1;
- gets(str+1);
- int pos=1;
- while (str[pos]!='=')
- pos++;
- dfs(pos+1,strlen(str+1),1);
- }
- int ans=Gauss();
- printf("Game %d\n",++Case);
- for (int i=0;i<n;i++)
- if (free_x[i])
- printf("Expected score for %c undefined\n",i+'a');
- else
- printf("Expected score for %c = %.3Lf\n",i+'a',x[i]);
- puts("");
- }
- return 0;
- }
POJ1487 Single-Player Games 高斯消元的更多相关文章
- 【CF446D】DZY Loves Games 高斯消元+矩阵乘法
[CF446D]DZY Loves Games 题意:一张n个点m条边的无向图,其中某些点是黑点,1号点一定不是黑点,n号点一定是黑点.问从1开始走,每次随机选择一个相邻的点走过去,经过恰好k个黑点到 ...
- POJ 1487:Single-Player Games 浮点数高斯消元
Single-Player Games Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 1287 Accepted: 36 ...
- 单(single):换根dp,表达式分析,高斯消元
虽说这题看大家都改得好快啊,但是为什么我感觉这题挺难.(我好菜啊) 所以不管怎么说那群切掉这题的大佬是不会看这篇博客的所以我要开始自嗨了. 这题,明显是树dp啊.只不过出题人想看你发疯,询问二合一了而 ...
- Codeforces 446D - DZY Loves Games(高斯消元+期望 DP+矩阵快速幂)
Codeforces 题目传送门 & 洛谷题目传送门 神仙题,%%% 首先考虑所有格子都是陷阱格的情况,那显然就是一个矩阵快速幂,具体来说,设 \(f_{i,j}\) 表示走了 \(i\) 步 ...
- HDU5088——Revenge of Nim II(高斯消元&矩阵的秩)(BestCoder Round #16)
Revenge of Nim II Problem DescriptionNim is a mathematical game of strategy in which two players tak ...
- hdu 5833 Zhu and 772002 高斯消元
Zhu and 772002 Problem Description Zhu and 772002 are both good at math. One day, Zhu wants to test ...
- SGU 275 To xor or not to xor 高斯消元求N个数中选择任意数XORmax
275. To xor or not to xor The sequence of non-negative integers A1, A2, ..., AN is given. You are ...
- POJ 1681---Painter's Problem(高斯消元)
POJ 1681---Painter's Problem(高斯消元) Description There is a square wall which is made of n*n small s ...
- HDU4870_Rating_双号从零单排_高斯消元求期望
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4870 原题: Rating Time Limit: 10000/5000 MS (Java/Other ...
随机推荐
- C# 与 SQL Server 的数据类型对应关系
(一)C#与SQL Server 2005(或以下版本): C# C#取值 SQL Server SQL Server取值 System.DateTime samlltime System.Objec ...
- C# 批量修改文件名
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- C#实现office文档转换为PDF格式
1.安装组件OfficeSaveAsPDFandXPS 需要安装office 2007 还有一个office2007的插件OfficeSaveAsPDFandXPS 下载地址 OfficeSave ...
- JS的call方法的作用解释,简单易懂
先看看关于call()的官方解释,“调用一个对象的一个方法,以另一个对象替换当前对象.”,看了这样的解释,或许让你更摸不着头脑了.看例子: var x = "我是全局变量"; // ...
- Ngnix + Tomcat负载均衡架构
一.nginx Nginx (发音同 engine x)是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行. 其特点是占有内 ...
- 2017-2018-2 20155303『网络对抗技术』Exp9:Web安全基础
2017-2018-2 『网络对抗技术』Exp9:Web安全基础 --------CONTENTS-------- 一.基础问题回答 1.SQL注入攻击原理,如何防御? 2.XSS攻击的原理,如何防御 ...
- C++ explicit 关键字
原文转自:http://www.cnblogs.com/ymy124/p/3632634.html 首先, C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造 ...
- Linux文件系统1---概述
1.引言 本文所述关于文件管理的系列文章主要是对陈莉君老师所讲述的文件系统管理知识讲座的整理.Linux可以支持不同的文件系统,它源于unix文件系统,也是unix文件系统的一大特色. 本文主要先 ...
- [转]RJ45接口说明
[转]http://blog.csdn.net/dog0138/article/details/7016351 1.前言 常见的RJ45接口有两类: 用于以太网网卡.路由器以太网接口等的DTE类型,可 ...
- 使用C#进行应用程序间通信(WPF与Unity通信)
首先程序主体来自网络,我只是应用在我自己的项目中,其中出现了一系列的问题,有些已经解决,有些使用了折中的方案,如果有大神能够给予知道,感激不尽! 首先是发送端程序: 这是我的程序任务执行主界面,此处已 ...