题目大意: 给一棵递归树,看链接图片,从根节点开始对于每个节点往它的子节点移动,直到叶子节点停止。每个节点选哪一个孩子节点继续往下走是随机的(等概率)。然后叶子节点都会标记一个数值,记为走到该节点的得分。

输入条件:先输入整数n(n=0时结束),接下来有n行(n <= 26),每一行会为前n个小写字母(每个字母作为一个变量)的描述。如a = (1 b)表示 f(a) = 1/2 * (1 + f(b))其中f(x)为x节点的得分期望。

现在对n个小写字母表示的变量节点,求出那个节点的得分期望即f(x) (x=a,b,c ...)。

这个题相当有意思,有意思在于它的输入——基于某个字符集的语义分析。递归向下分析的策略,而且是非常典型LL(1)文法!

S -> XWEWT

X -> (X)|a|b|c|...|z

E -> '='

W -> {Blank}|空

T -> (U)

U -> T|X|I

U -> UwU

w ->  {Blank}

I -> [+|-]{Digit}+[.{Digit}]

这道题另外一个关键点是将T转化成方程式,然后综合这n个方程式,使用gauss消元求解。

gauss消元其实就是线性代数中,化简行列式然后进行求解。不会的亲们回去好好看看线性代数的书,不要看网上某些人写的不清不楚的报告。

只是有一点需要注意:计算机中的数字是有界的,要时刻注意数字边界问题!

还有,很多事情需要自己亲身实践,我贡献了很多次WA,一个大原因是听人家要排除输出"-0.000"的问题。

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
int alpha[]={},n;
int getint(char *mes){
int i=;
while(mes[i]!='\0' && (mes[i]<'' || mes[i]>'')) i++;
return atoi(mes+i);
}
struct equation{
double ec[];
equation(){ for(int i=;i<;i++) ec[i]=; }
equation operator+(const equation & S){ equation E; for(int i=;i<;i++) E.ec[i]= ec[i]+S.ec[i]; return E; }
equation operator+=(const equation & S){ for(int i=;i<;i++) ec[i]+=S.ec[i]; return *this; }
equation operator*(double rat){ equation E; for(int i=;i<;i++) E.ec[i]= ec[i]*rat; return E; }
void print(){ for(int i=;i<n-;i++) printf("%f*%c + ",ec[i],i+'a'); printf("%f*%c = %f\n",ec[n-],n-+'a',ec[]); }
};
char mes[]; int idx;
equation getEquation(){
equation E;
if(mes[idx] == '('){
queue<equation> que; idx++;
while(){
while(!alpha[mes[idx]]) idx++; //跳到下一个合法字母
if(mes[idx]==')') break;
que.push(getEquation());
} idx++;
double quesize=1.0/que.size();
while(!que.empty()) E += que.front()*quesize, que.pop();
}else if(mes[idx]>=''&&mes[idx]<='' || mes[idx]=='-' || mes[idx]=='+'){
double t=,sign=;
if(mes[idx]=='-' || mes[idx]=='+'){
if(mes[idx]=='-') sign=-;
idx++;
}
while(mes[idx]>=''&&mes[idx]<=''){
t = t* + mes[idx]-'';
idx++;
}
if(mes[idx]=='.'){
double tt=0.1; idx++;
while(mes[idx]>=''&&mes[idx]<=''){
t += tt*(mes[idx]-'');
tt *= 0.1; idx++;
}
}
//printf("t = %f, sign = %f\n",t,sign);
E.ec[]=t*sign;
}else { // 'a' ---- 'z'
E.ec[mes[idx]-'a']=;
idx++;
}
while(!alpha[mes[idx]]) idx++; //跳到下一个合法字母
return E;
}
equation parse(){
while(mes[idx]<'a' || mes[idx]>'z') idx++;
int c=mes[idx]-'a';
while(mes[idx]!='=') idx++; idx++;
while(!alpha[mes[idx]]) idx++; //跳到下一个合法字母
equation E = getEquation();
E.ec[]=-E.ec[];
E.ec[c]-=;
return E;
}
double mat[][];
int setted[],rid[];
const double zero=1e-;
void unset(int x){
if(!setted[x]) return;
setted[x]=;
for(int i=x-;i>=;i--)
if(fabs(mat[i][x]) > zero)
unset(i);
}
void gauss(){
memset(setted,-,sizeof(setted));
for(int r=;r<n;r++){
int c=r;
int nonzero=-; double minv=1e99;
for(int i=c;i<n;i++)
if(fabs(mat[i][c]) > zero && fabs(mat[i][c]-) < minv)
nonzero=i, minv=mat[i][c];
if(nonzero < ) unset(r);
else {
double rat=/mat[nonzero][c];
for(int i=c;i<=n;i++) mat[nonzero][i] *= rat, swap(mat[nonzero][i],mat[r][i]);
for(int i=;i<n;i++)
if(i!=r && fabs(mat[i][c]) > zero){
rat = mat[i][c];
for(int j=c;j<=n;j++)
mat[i][j] -= rat*mat[r][j];
}
}
}
}
int main()
{
// init the legal alpha
for(int i='';i<='';i++) alpha[i]=;
for(int i='a';i<='z';i++) alpha[i]=;
alpha['.']=; alpha['(']=; alpha[')']=;
alpha['+']=; alpha['-']=;
// main logic
int game=;
do {
gets(mes); n=getint(mes);
if(n <= ) break;
for(int i=;i<n;i++){
gets(mes); idx=;
equation E = parse();
//E.print();
for(int j=;j<;j++)
mat[i][j]=E.ec[j];
}
for(int j=;j<n;j++)
mat[j][n]=mat[j][];
printf("Game %d\n",game++);
gauss();
for(int j=;j<n;j++)
if(setted[j]) {
/* 排除输出 -0.000 的问题, 这里多余了
int tt=0;
for(int i=0;i<n;i++){
sprintf(mes,"%.3f",mat[j][n]);
tt=0;
if(memcmp("-0.000",mes,5)==0) tt=1;
printf("Expected score for %c = %s\n",j+'a',mes+tt);
}
*/
printf("Expected score for %c = %.3f\n",j+'a',mat[j][n]);
}
else printf("Expected score for %c undefined\n",j+'a');
puts("");
}while();
return ;
}

poj1487的更多相关文章

  1. POJ1487 Single-Player Games 高斯消元

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ1487 题解概括 给出多个树形结构,由小写字母和数字表示,每个小写字母表示一棵小树.现在,以a为根节点 ...

  2. poj分类 很好很有层次感。

    初期: 一.基本算法:      (1)枚举. (poj1753,poj2965)      (2)贪心(poj1328,poj2109,poj2586)      (3)递归和分治法.      ( ...

  3. 【转】POJ题目分类推荐 (很好很有层次感)

    OJ上的一些水题(可用来练手和增加自信) (poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094)初期: 一. ...

  4. 【转】ACM训练计划

    [转] POJ推荐50题以及ACM训练方案 -- : 转载自 wade_wang 最终编辑 000lzl POJ 推荐50题 第一类 动态规划(至少6题, 和 必做) 和 (可贪心) (稍难) 第二类 ...

  5. POJ 题目分类(转载)

    Log 2016-3-21 网上找的POJ分类,来源已经不清楚了.百度能百度到一大把.贴一份在博客上,鞭策自己刷题,不能偷懒!! 初期: 一.基本算法: (1)枚举. (poj1753,poj2965 ...

  6. (转)POJ题目分类

    初期:一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推. ...

  7. acm常见算法及例题

    转自:http://blog.csdn.net/hengjie2009/article/details/7540135 acm常见算法及例题  初期:一.基本算法:     (1)枚举. (poj17 ...

  8. poj分类

    初期: 一.基本算法:      (1)枚举. (poj1753,poj2965)      (2)贪心(poj1328,poj2109,poj2586)      (3)递归和分治法.      ( ...

  9. 转载 ACM训练计划

    leetcode代码 利用堆栈:http://oj.leetcode.com/problems/evaluate-reverse-polish-notation/http://oj.leetcode. ...

随机推荐

  1. UVA - 10131Is Bigger Smarter?(DAG上的DP)

    题目:UVA - 10131Is Bigger Smarter? (DAG) 题目大意:给出一群大象的体重和IQ.要求挑选最多的大象,组成一个序列.严格的体重递增,IQ递减的序列.输出最多的大象数目和 ...

  2. 聚类算法初探(四)K-means

    最近由于工作需要,对聚类算法做了一些相关的调研.现将搜集到的资料和自己对算法的一些理解整理如下,供大家参考. 另外在算法代码方面,我也做了一些实现(包括串行和并行),欢迎感兴趣的朋友探讨和交流. 第一 ...

  3. 怎样在xcode中使用storyboard

    StoryBoard是iOS 5的新特征,目的是取代历史悠久的NIB/XIB,对于已经习惯了xib文件的孩子们来说,StoryBoard还不是那么熟悉.经过两天的研究,有了一些心得,在此分享. 一.怎 ...

  4. mobilebone.js 移动web APP单页切换骨架

    轻便体积小 原生无依赖 插件可扩展 设计无限制 动效可定制 动静两相宜 能进亦能退 桌面也兼修 一句话功能简介跟传统网页浏览的差别仅仅在于无刷新! 例如,我们浏览首页,首页上有个如下HTML链接: & ...

  5. z-index解决弹出层遮罩层覆盖子div不能显示输出的问题

    // 添加以下代码来进行测试: // ajax 发生错误,就会执行$('body').ajaxError(function(e, xhr, setting, text){    // e - even ...

  6. 蜗牛爱课 - iOS7、8模态半透明弹出框

    //源Controller中跳转方法实现 MKDialogController *controller = [[MKDialogController alloc] init]; controller. ...

  7. MapReduce详解

    1.mapreduce之shuffle http://blog.csdn.net/thomas0yang/article/details/8562910 2.彻底了解mapreduce核心Shuffl ...

  8. JNI加载Native Library 以及 跨线程和Qt通信

    Part1 Java Native Interface-JNI-JAVA本地调用 JNI标准是Java平台的一部分, 允许Java代码和其他语言进行交互; 开始实现-> Step 1) 编写Ja ...

  9. mysql优化(2) 观察mysql进程状态

    环境准备,安装sysbench wget http://nchc.dl.sourceforge.net/project/sysbench/sysbench/0.4.12/sysbench-0.4.12 ...

  10. JS中定义类的方法<转>

    转载地址:http://blog.csdn.net/sdlfx/article/details/1842218 PS(个人理解): 1) 类通过prototype定义的成员(方法或属性),是每个类对象 ...