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 ...
随机推荐
- Spring第一个helloWorld
Spring 简介: 轻量级:Spring是非侵入性的-基于Spring开发的应用中的对象可以不依赖于Spring的API 依赖注入(DI—dependdency injection.IOC) 面向切 ...
- C语言入门教程-(6)运算符
1.运算符概述 运算符是一种编译器执行特定的数学或逻辑操作的符号.C语言提供了以下类型的运算符: 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 条件运算符 其他运算符 2.算术运算符 算术 ...
- d2-admin中那些不错的技巧
d2-admin基于vue-cli3 路由相关 刷新路由,参照官方 组件内的守卫 但是搞不明白为何加了句 render:h => h() { path: 'refresh', name: 'r ...
- [转]bus error与segment error
在c程序中,经常会遇到段错误(segment error)和总线错误(bus error),这两种问题出现的原因可能如下 段错误: 对一个NULL指针解引用. 访问程序进程以外的内存空间. 实际上,第 ...
- jQuery——Js与jQuery的相互转换
$()与jQuery() jQuery中$函数,根据传入参数的不同,进行不同的调用,实现不同的功能.返回的是jQuery对象 jQuery这个js库,除了$之外,还提供了另外一个函数:jQuery j ...
- ActiveMQ安装与入门程序 & JMS的消息结构
1.Activemq安装 直接到官网下载:记住apache的官网是域名反过来,比如我们找activemq就是activemq.apache.org. 最新版本要求最低的JDK是8,所以最好在电脑装多个 ...
- 原生JS给元素添加class属性
有下面这三种简单语句. document.getElementsByTagName('body')[0].className = 'snow-container'; //设置为新的 document ...
- SpringBoot三种配置Dubbo的方式
*必须首先导入dubbo-starter (1).使用SpringBoot配置文件(application.properties或application.yml) dubbo.application. ...
- 利用capability特征加强Linux系统安全【转】
转自:https://blog.csdn.net/fivedragon/article/details/676849 1.简介 UNIX是一种安全操作系统,它给普通用户尽可能低的权限,而把全部的系统权 ...
- Linux内存管理--基本概念【转】
转自:http://blog.csdn.net/myarrow/article/details/8624687 1. Linux物理内存三级架构 对于内存管理,Linux采用了与具体体系架构不相关的设 ...