欢迎访问~原文出处——博客园-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 高斯消元的更多相关文章

  1. 【CF446D】DZY Loves Games 高斯消元+矩阵乘法

    [CF446D]DZY Loves Games 题意:一张n个点m条边的无向图,其中某些点是黑点,1号点一定不是黑点,n号点一定是黑点.问从1开始走,每次随机选择一个相邻的点走过去,经过恰好k个黑点到 ...

  2. POJ 1487:Single-Player Games 浮点数高斯消元

    Single-Player Games Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 1287   Accepted: 36 ...

  3. 单(single):换根dp,表达式分析,高斯消元

    虽说这题看大家都改得好快啊,但是为什么我感觉这题挺难.(我好菜啊) 所以不管怎么说那群切掉这题的大佬是不会看这篇博客的所以我要开始自嗨了. 这题,明显是树dp啊.只不过出题人想看你发疯,询问二合一了而 ...

  4. Codeforces 446D - DZY Loves Games(高斯消元+期望 DP+矩阵快速幂)

    Codeforces 题目传送门 & 洛谷题目传送门 神仙题,%%% 首先考虑所有格子都是陷阱格的情况,那显然就是一个矩阵快速幂,具体来说,设 \(f_{i,j}\) 表示走了 \(i\) 步 ...

  5. 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 ...

  6. hdu 5833 Zhu and 772002 高斯消元

    Zhu and 772002 Problem Description Zhu and 772002 are both good at math. One day, Zhu wants to test ...

  7. 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 ...

  8. POJ 1681---Painter's Problem(高斯消元)

    POJ   1681---Painter's Problem(高斯消元) Description There is a square wall which is made of n*n small s ...

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

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

随机推荐

  1. castle动态代理的使用

    转自:https://blog.csdn.net/educast/article/details/6565447#动态代理的原理 原理其实很简单,就是在运行时生成新的对象,姑且叫做T,并使T继承自需要 ...

  2. 网站程序CMS识别

    CMS cms一般有dedecms(织梦),dzcms,phpweb,phpwind,phpcms,ecshop,dvbbs,siteweaver,aspcms,帝国,zblog,wordpress等 ...

  3. dos 设置 Windows 网络命令

    dos 设置Windows 命令: netsh interface ip set address name="本地连接" source=static addr=172.16.12. ...

  4. Docker镜像命令

    ①docker images [Options] 用途:列出本地主机上的镜像 Options说明: -a:列出本地所有的镜像(含中间映像层) -q:只显示镜像ID --digests:显示镜像的摘要信 ...

  5. IP分片丢失重传 - Sacrifice的日志 - 网易博客

        尽管IP分片看起来是是透明的,但有一点让人不想使用它:即使只丢失一片数据也要重传整个数据报.为什么会发生这种情况呢?     因为IP层本身没有超时重传的机制--由更高层来负责超时和重传(TC ...

  6. python 读取文件时报错UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 205: illegal multib

    python 读取文件时报错UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 205: illegal multib ...

  7. Java SSH远程执行Shell命令、shell脚本实现(Ganymed SSH)

    jar包下载地址: http://www.ganymed.ethz.ch/ssh2/ 此源码的好处就是没有依赖很多其他的包,拷贝过来干干净净.具体代码实现可以看下文,或参考官方文档,在下载的压缩包里g ...

  8. V$SQLAREA

    1.查看消耗资源最多的SQL: SELECT hash_value, executions, buffer_gets, disk_reads, parse_calls FROM V$SQLAREA W ...

  9. 001_linux下的log

    如果愿意在Linux环境方面花费些时间,首先就应该知道日志文件的所在位置以及它们包含的内容.在系统运行正常的情况下学习了解这些不同的日志文件有助于你在遇到紧急情况时从容找出问题并加以解决. 以下介绍的 ...

  10. centos6.5环境disconf管理端安装配置详解

    操作系统:centos6.5 x86_64 安装目录/data 1.安装nginx1.10.1 rpm -ivh http://nginx.org/packages/centos/6/noarch/R ...