在推导期望方程时我们常常会遇到dp[i]和其他项有关联,那么这时候我们就难以按某个顺序进行递推

即难以通过已经确定的项来求出新的项

即未知数的相互关系是循环的

但是我们又可以确定和dp[i]相关联的项是有规律的,即存在一个可以递推dp[i]的通项公式,那么不妨设置未知数,通过原方程的迭代来打破这种循环

为了完成递推,我们需要通过递推和dp[i]有关的参数来间接求出dp[i]

比如递推方程dp[i]总是和dp[1]有关,那么我们可以肯定dp[i]=ai*dp[1]+b[i]

那么用这个方程进行迭代,最后可以发现ai是能够逆着递推的

zoj3329:dp[i]=a[i]dp[0]+b[i]

这题dp[i]总是和dp[0]有关,假设dp[i+k]的值都知道了(等价于常数b[i]),那么a[i]就是个可以递推的项

hdu:dp[i][j]=a[j]*dp[i][i]+c[j]

hdu4035:树上迭代,因为正常的顺序是从叶子推导到根,但是每个结点会受到dp[rt]和dp[fa]的影响, 所以这两项要用两个参数来迭代

  dp[u]=a[u]*dp[rt]+b[u]*dp[fa]+c[u]

#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath> using namespace std; const int MAXN = + ; double e[MAXN], k[MAXN];
double A[MAXN], B[MAXN], C[MAXN]; vector<int> v[MAXN]; bool search(int i, int fa)
{
if ( v[i].size() == && fa != - )
{
A[i] = k[i];
B[i] = - k[i] - e[i];
C[i] = - k[i] - e[i];
return true;
} A[i] = k[i];
B[i] = ( - k[i] - e[i]) / v[i].size();
C[i] = - k[i] - e[i];
double tmp = ; for (int j = ; j < (int)v[i].size(); j++)
{
if ( v[i][j] == fa ) continue;
if ( !search(v[i][j], i) ) return false;
A[i] += A[v[i][j]] * B[i];
C[i] += C[v[i][j]] * B[i];
tmp += B[v[i][j]] * B[i];
}
if ( fabs(tmp - ) < 1e- ) return false;
A[i] /= - tmp;
B[i] /= - tmp;
C[i] /= - tmp;
return true;
} int main()
{
int nc, n, s, t; cin >> nc;
for (int ca = ; ca <= nc; ca++)
{
scanf("%d",&n);
for (int i = ; i <= n; i++)
v[i].clear(); for (int i = ; i < n; i++)
{
scanf("%d%d",&s,&t);
v[s].push_back(t);
v[t].push_back(s);
}
for (int i = ; i <= n; i++)
{
scanf("%lf%lf",&k[i],&e[i]);
k[i] /= 100.0;
e[i] /= 100.0;
} cout << "Case " << ca << ": ";
if ( search(, -) && fabs( - A[]) > 1e- )
cout << C[]/( - A[]) << endl;
else
cout << "impossible" << endl;
}
return ;
}
#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath> using namespace std; const int MAXN = + ; double e[MAXN], k[MAXN];
double A[MAXN], B[MAXN], C[MAXN]; vector<int> v[MAXN]; bool search(int i, int fa)
{
if ( v[i].size() == && fa != - )
{
A[i] = k[i];
B[i] = - k[i] - e[i];
C[i] = - k[i] - e[i];
return true;
} A[i] = k[i];
B[i] = ( - k[i] - e[i]) / v[i].size();
C[i] = - k[i] - e[i];
double tmp = ; for (int j = ; j < (int)v[i].size(); j++)
{
if ( v[i][j] == fa ) continue;
if ( !search(v[i][j], i) ) return false;
A[i] += A[v[i][j]] * B[i];
C[i] += C[v[i][j]] * B[i];
tmp += B[v[i][j]] * B[i];
}
if ( fabs(tmp - ) < 1e- ) return false;
A[i] /= - tmp;
B[i] /= - tmp;
C[i] /= - tmp;
return true;
} int main()
{
int nc, n, s, t; cin >> nc;
for (int ca = ; ca <= nc; ca++)
{
scanf("%d",&n);
for (int i = ; i <= n; i++)
v[i].clear(); for (int i = ; i < n; i++)
{
scanf("%d%d",&s,&t);
v[s].push_back(t);
v[t].push_back(s);
}
for (int i = ; i <= n; i++)
{
scanf("%lf%lf",&k[i],&e[i]);
k[i] /= 100.0;
e[i] /= 100.0;
} cout << "Case " << ca << ": ";
if ( search(, -) && fabs( - A[]) > 1e- )
cout << C[]/( - A[]) << endl;
else
cout << "impossible" << endl;
}
return ;
}
#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath> using namespace std; const int MAXN = + ; double e[MAXN], k[MAXN];
double A[MAXN], B[MAXN], C[MAXN]; vector<int> v[MAXN]; bool search(int i, int fa)
{
if ( v[i].size() == && fa != - )
{
A[i] = k[i];
B[i] = - k[i] - e[i];
C[i] = - k[i] - e[i];
return true;
} A[i] = k[i];
B[i] = ( - k[i] - e[i]) / v[i].size();
C[i] = - k[i] - e[i];
double tmp = ; for (int j = ; j < (int)v[i].size(); j++)
{
if ( v[i][j] == fa ) continue;
if ( !search(v[i][j], i) ) return false;
A[i] += A[v[i][j]] * B[i];
C[i] += C[v[i][j]] * B[i];
tmp += B[v[i][j]] * B[i];
}
if ( fabs(tmp - ) < 1e- ) return false;
A[i] /= - tmp;
B[i] /= - tmp;
C[i] /= - tmp;
return true;
} int main()
{
int nc, n, s, t; cin >> nc;
for (int ca = ; ca <= nc; ca++)
{
scanf("%d",&n);
for (int i = ; i <= n; i++)
v[i].clear(); for (int i = ; i < n; i++)
{
scanf("%d%d",&s,&t);
v[s].push_back(t);
v[t].push_back(s);
}
for (int i = ; i <= n; i++)
{
scanf("%lf%lf",&k[i],&e[i]);
k[i] /= 100.0;
e[i] /= 100.0;
} cout << "Case " << ca << ": ";
if ( search(, -) && fabs( - A[]) > 1e- )
cout << C[]/( - A[]) << endl;
else
cout << "impossible" << endl;
}
return ;
}
#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath> using namespace std; const int MAXN = + ; double e[MAXN], k[MAXN];
double A[MAXN], B[MAXN], C[MAXN]; vector<int> v[MAXN]; bool search(int i, int fa)
{
if ( v[i].size() == && fa != - )
{
A[i] = k[i];
B[i] = - k[i] - e[i];
C[i] = - k[i] - e[i];
return true;
} A[i] = k[i];
B[i] = ( - k[i] - e[i]) / v[i].size();
C[i] = - k[i] - e[i];
double tmp = ; for (int j = ; j < (int)v[i].size(); j++)
{
if ( v[i][j] == fa ) continue;
if ( !search(v[i][j], i) ) return false;
A[i] += A[v[i][j]] * B[i];
C[i] += C[v[i][j]] * B[i];
tmp += B[v[i][j]] * B[i];
}
if ( fabs(tmp - ) < 1e- ) return false;
A[i] /= - tmp;
B[i] /= - tmp;
C[i] /= - tmp;
return true;
} int main()
{
int nc, n, s, t; cin >> nc;
for (int ca = ; ca <= nc; ca++)
{
scanf("%d",&n);
for (int i = ; i <= n; i++)
v[i].clear(); for (int i = ; i < n; i++)
{
scanf("%d%d",&s,&t);
v[s].push_back(t);
v[t].push_back(s);
}
for (int i = ; i <= n; i++)
{
scanf("%lf%lf",&k[i],&e[i]);
k[i] /= 100.0;
e[i] /= 100.0;
} cout << "Case " << ca << ": ";
if ( search(, -) && fabs( - A[]) > 1e- )
cout << C[]/( - A[]) << endl;
else
cout << "impossible" << endl;
}
return ;
}
#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath> using namespace std; const int MAXN = + ; double e[MAXN], k[MAXN];
double A[MAXN], B[MAXN], C[MAXN]; vector<int> v[MAXN]; bool search(int i, int fa)
{
if ( v[i].size() == && fa != - )
{
A[i] = k[i];
B[i] = - k[i] - e[i];
C[i] = - k[i] - e[i];
return true;
} A[i] = k[i];
B[i] = ( - k[i] - e[i]) / v[i].size();
C[i] = - k[i] - e[i];
double tmp = ; for (int j = ; j < (int)v[i].size(); j++)
{
if ( v[i][j] == fa ) continue;
if ( !search(v[i][j], i) ) return false;
A[i] += A[v[i][j]] * B[i];
C[i] += C[v[i][j]] * B[i];
tmp += B[v[i][j]] * B[i];
}
if ( fabs(tmp - ) < 1e- ) return false;
A[i] /= - tmp;
B[i] /= - tmp;
C[i] /= - tmp;
return true;
} int main()
{
int nc, n, s, t; cin >> nc;
for (int ca = ; ca <= nc; ca++)
{
scanf("%d",&n);
for (int i = ; i <= n; i++)
v[i].clear(); for (int i = ; i < n; i++)
{
scanf("%d%d",&s,&t);
v[s].push_back(t);
v[t].push_back(s);
}
for (int i = ; i <= n; i++)
{
scanf("%lf%lf",&k[i],&e[i]);
k[i] /= 100.0;
e[i] /= 100.0;
} cout << "Case " << ca << ": ";
if ( search(, -) && fabs( - A[]) > 1e- )
cout << C[]/( - A[]) << endl;
else
cout << "impossible" << endl;
}
return ;
}

概率dp的迭代方式小结——zoj3329,hdu4089,hdu4035的更多相关文章

  1. ZOJ 3329-One Person Game(概率dp,迭代处理环)

    题意: 三个色子有k1,2,k3个面每面标号(1-k1,1-k2,1-k3),一次抛三个色子,得正面向上的三个编号,若这三个标号和给定的三个编号a1,b1,c1对应则总和置零,否则总和加上三个色子标号 ...

  2. ZOJ3329之经典概率DP

    One Person Game Time Limit: 1 Second      Memory Limit: 32768 KB      Special Judge There is a very ...

  3. 概率dp小结

    好久之前学过,记得是一次亚洲区的前几天看了看概率dp,然后亚洲区就出了一道概率dp,当时虽然做上了,但是感觉有很多地方没懂,今天起早温习了一下,觉得很多地方茅塞顿开,果然学习的话早上效果最好了. 首先 ...

  4. HDU4089/Uva1498 Activation 概率DP(好题)

    题意:Tomato要在服务器上激活一个游戏,一开始服务器序列中有N个人,他排在第M位,每次服务器会对序列中第一位的玩家进行激活,有四种结果: 1.有p1的概率会激活失败,这时候序列的状态是不变的.2. ...

  5. [HDU 4089]Activation[概率DP]

    题意: 有n个人排队等着在官网上激活游戏.Tomato排在第m个. 对于队列中的第一个人.有以下情况: 1.激活失败,留在队列中等待下一次激活(概率为p1) 2.失去连接,出队列,然后排在队列的最后( ...

  6. 动态规划之经典数学期望和概率DP

    起因:在一场训练赛上.有这么一题没做出来. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6829 题目大意:有三个人,他们分别有\(X,Y,Z\)块钱 ...

  7. HDU 4576 Robot(概率dp)

    题目 /*********************复制来的大致题意********************** 有N个数字,M个操作, 区间L, R. 然后问经过M个操作后落在[L, R]的概率. * ...

  8. HDU 4089 Activation(概率DP)(转)

    11年北京现场赛的题目.概率DP. 公式化简起来比较困难....而且就算结果做出来了,没有考虑特殊情况照样会WA到死的.... 去参加区域赛一定要考虑到各种情况.   像概率dp,公式推出来就很容易写 ...

  9. UVALive 6672 Bonus Cards 概率dp

    题意呢 就是有两种售票方式 一种是icpc 一种是其他方式 icpc抢票成功的概率是其他方式的2倍…… 这时 一个人出现了 他通过内幕知道了两种抢票方式各有多少人 他想知道自己如果用icpc抢票成功的 ...

随机推荐

  1. 框架集 frameset

    框架集和内联框架的作用类似,都用于在一个页面中引入其他的外部的页面 框架集可以同时引入多个页面,而内联框架引入一个, 在h5标准中,推荐使用框架集,而不使用内联框架 使用 frameset 来创建一个 ...

  2. docker Dcokerfile学习---构建nginx环境

    1.创建项目目录并上传包 $ mkdir docker_nginx $ cd docker_nginx 下载nginx包 $ wget http://nginx.org/download/nginx- ...

  3. 关于synchronized和Lock

    原文链接:关于volatile关键字解析,synchronized和Lock参考 深入浅出,解释的非常清楚,有条理~~~ 以下为转载内容: Java并发编程:volatile关键字解析 volatil ...

  4. CSS——浮动及应用&清除浮动

    浮动(float) 1.普通流(normal flow) 这个单词很多人翻译为 文档流 , 字面翻译 普通流 或者标准流都可以. 前面我们说过,网页布局的核心,就是用CSS来摆放盒子位置.如何把盒子摆 ...

  5. 7.12模拟T2(套路容斥+多项式求逆)

    Description: \(n<=10,max(w)<=1e6\) 题解: 考虑暴力,相当于走多维格子图,不能走有些点. 套路就是设\(f[i]\)表示第一次走到i的方案数 \(f[i] ...

  6. php-fpm 服务

    编译安装PHP的时候已经加入了--enable-fpm 在此基础上启动php-fpm服务 cp /usr/local/php/etc/php-fpm.conf.default /usr/local/p ...

  7. 原生js实现文件下载并设置请求头header

    原生js实现文件下载并设置请求头header const token="自行定义";//如果有 /** * 向指定路径发送下载请求 * @param{String} url 请求路 ...

  8. [JZOJ 5804] 简单的序列

    思路: 似乎和某次培训的题很像啊... 将左括号记为1,右括号记为-1,那么最终一定加和为0,然后再求最小前缀和. 用dp解决即可. #include <bits/stdc++.h> us ...

  9. javascript html jquery 入门

    就开发难易程度来说,现在普遍使用jquery,本人学习jquery html css时间不长,以前写过Flex. CSS+JS+HTML组成HTML开发三驾马车.学习js开发我认为怎么入门十分重要.根 ...

  10. [zz]使用OleDb,将Excel导入DataSet

    本方法,将传入的Excel文件内所有的Sheet内的数据都填充入DataSet中.这是一个简单快捷的方法,不足之处是不适合带有格式复杂的Excel文件.(比如:有合并单元格的) public clas ...