概率与期望 HDU 4405 Aeroplane chess(飞行棋)
来源:互联网 发布:js改变color rgb 编辑:程序博客网 时间:2024/05/24 07:11
题目:
Description
Hzz loves aeroplane chess very much. The chess map contains N+1 grids labeled from 0 to N. Hzz starts at grid 0. For each step he throws a dice(a dice have six faces with equal probability to face up and the numbers on the faces are 1,2,3,4,5,6). When Hzz is at grid i and the dice number is x, he will moves to grid i+x. Hzz finishes the game when i+x is equal to or greater than N.
There are also M flight lines on the chess map. The i-th flight line can help Hzz fly from grid Xi to Yi (0<Xi<Yi<=N) without throwing the dice. If there is another flight line from Yi, Hzz can take the flight line continuously. It is granted that there is no two or more flight lines start from the same grid.
Please help Hzz calculate the expected dice throwing times to finish the game.
There are also M flight lines on the chess map. The i-th flight line can help Hzz fly from grid Xi to Yi (0<Xi<Yi<=N) without throwing the dice. If there is another flight line from Yi, Hzz can take the flight line continuously. It is granted that there is no two or more flight lines start from the same grid.
Please help Hzz calculate the expected dice throwing times to finish the game.
Input
There are multiple test cases.
Each test case contains several lines.
The first line contains two integers N(1≤N≤100000) and M(0≤M≤1000).
Then M lines follow, each line contains two integers Xi,Yi(1≤Xi<Yi≤N).
The input end with N=0, M=0.
Each test case contains several lines.
The first line contains two integers N(1≤N≤100000) and M(0≤M≤1000).
Then M lines follow, each line contains two integers Xi,Yi(1≤Xi<Yi≤N).
The input end with N=0, M=0.
Output
For each test case in the input, you should output a line indicating the expected dice throwing times. Output should be rounded to 4 digits after decimal point.
Sample Input
2 08 32 44 57 80 0
Sample Output
1.16672.3441
这个题目还是有点复杂的。
不过有一个地方可以化简,那就是,因为我们基本上都是用累加刷表的形式来算的,所以如果有2条飞行线(flight line)连起来,这个是不用考虑的。
也就是说,我们就当没有这种现象,来写代码就可以了,如果有这种现象出现,答案也是一样的。
我的第一种思路是,用list记录到底某个格子的概率,用times记录从0到这个格子所需要的平均次数。
代码:
#include<iostream>#include<string.h>#include<iomanip>using namespace std;int n, m;double list[100011];//概率double times[100011];//平均次数int fly[100011];//飞行线double f(int i,int k){if (i < 0)return 0;if (i >= n - 5 && k == n)return list[i] * (7 - n + i) / 6;return list[i] / 6;}double ft(int i,int k){if (i < 0)return 0;return f(i, k) * (times[i] + 1);}int main(){int start, end_;double r1, r2;while (cin >> n >> m){if (n == 0)break;memset(fly, 0, sizeof(fly));for (int i = 0; i < m; i++){cin >> start >> end_;fly[start] = end_;}memset(list, 0, sizeof(list));memset(times, 0, sizeof(times));list[0] = 1;times[0] = 0;for (int i = 1; i <= n; i++){list[i] += f(i - 1, i) + f(i - 2, i) + f(i - 3, i) + f(i - 4, i) + f(i - 5, i) + f(i - 6, i);times[i] += ft(i - 1, i) + ft(i - 2, i) + ft(i - 3, i) + ft(i - 4, i) + ft(i - 5, i) + ft(i - 6, i);if (list[i] > 0)times[i] /= list[i];if (fly[i]){list[fly[i]] += list[i];times[fly[i]] += list[i] * times[i];list[i] = 0;}}cout << fixed << setprecision(4) << times[n] << endl;}return 0;}
这个是78ms的
因为在AC之前出现过几次wrong answer,我以为是除0的问题,所以在这个代码完成之前我是用另外一个代码AC的。
我的第二种思路:times不表示次数,而表示次数的期望。
代码:
#include<iostream>#include<string.h>#include<iomanip>using namespace std;int n, m;double list[100011];//概率double times[100011];//次数的期望int fly[100011];//飞行线double f(int i,int k){if (i < 0)return 0;if (i >= n - 5 && k == n)return list[i] * (7 - n + i) / 6;return list[i] / 6;}double ft(int i,int k){if (i < 0)return 0;if (list[i] == 0)return 0;if (i >= n - 5 && k == n)return (times[i] + list[i])*(7 - n + i) / 6;return (times[i] + list[i]) / 6;}int main(){int start, end_;double r1, r2;while (cin >> n >> m){if (n == 0)break;memset(fly, 0, sizeof(fly));for (int i = 0; i < m; i++){cin >> start >> end_;fly[start] = end_;}memset(list, 0, sizeof(list));memset(times, 0, sizeof(times));list[0] = 1;times[0] = 0;for (int i = 1; i <= n; i++){list[i] += f(i - 1, i) + f(i - 2, i) + f(i - 3, i) + f(i - 4, i) + f(i - 5, i) + f(i - 6, i);times[i] += ft(i - 1, i) + ft(i - 2, i) + ft(i - 3, i) + ft(i - 4, i) + ft(i - 5, i) + ft(i - 6, i);if (fly[i]){list[fly[i]] += list[i];times[fly[i]] += times[i];list[i] = 0;}}cout << fixed << setprecision(4) << times[n] << endl;}return 0;}
这个代码最后一次的修改是最后的 if 里面的代码。AC是140ms。
因为2个代码几乎是差不多的,所以我把前面那个代码也对应的改了交了AC了。(本文的3个代码都是AC了的)
在我写到这里的时候,惊奇的发现,求期望我居然是从0往后顺着推的!
明明应该从n往前倒推啊啊啊。。。
然后我又写了一下逆推的算法,只写了2分钟就写完了,提交直接AC,而且只有31ms。逆推比顺推简单太多太多了。
这里的times的意思又不一样,指的是从每个格子到底终点所需要的平均次数。
代码:
#include<iostream>#include<string.h>#include<iomanip>using namespace std;int n, m;double times[100011];//平均次数int fly[100011];//飞机int main(){int start, end_;double r1, r2;while (cin >> n >> m){if (n == 0)break;memset(fly, 0, sizeof(fly));for (int i = 0; i < m; i++){cin >> start >> end_;fly[start] = end_;}memset(times, 0, sizeof(times));for (int i = n - 1; i >= 0; i--){if (fly[i])times[i] = times[fly[i]];else times[i] = (times[i + 1] + times[i + 2] + times[i + 3] + times[i + 4] + times[i + 5] + times[i + 6]) / 6 + 1;}cout << fixed << setprecision(4) << times[0] << endl;}return 0;}
关于为什么反向求比正向求要简单的多的多,请点击查看我的博客
2 0
- 概率与期望 HDU 4405 Aeroplane chess(飞行棋)
- hdu 4405 Aeroplane chess (概率与期望)
- [hdu 4405] Aeroplane chess [概率DP & 期望]
- HDU 4405 Aeroplane chess (概率DP求期望)
- HDU 4405 - Aeroplane chess (概率DP 求期望)
- hdu 4405 Aeroplane chess (概率DP+求期望)
- HDU 4405 Aeroplane chess 概率dp 求期望(入门)
- HDU 4405 Aeroplane chess(全期望公式-概率dp)
- HDU 4405 Aeroplane chess (概率DP & 期望)
- HDU 4405 Aeroplane chess (概率-期望DP)【模板】
- HDU 4405 Aeroplane chess(概率DP求期望)
- HDU 4405 Aeroplane chess(期望)
- HDU 4405 Aeroplane chess(期望DP)
- HDU 4405 Aeroplane chess (简单期望)
- HDU 4405 Aeroplane chess 概率dp求期望
- 简单概率dp(期望)-hdu-4405-Aeroplane chess
- hdu 4405 Aeroplane chess【概率DP求期望】
- Aeroplane chess 4405 hdu 概率DP求期望入门题
- android studio 计算器代码 不能连续运算
- 后缀数组入门——初步理解及模板
- 闲杂小记(三)
- 【Android】在Recent列表中隐藏App
- JavaEE web(2)
- 概率与期望 HDU 4405 Aeroplane chess(飞行棋)
- 练习场acm 题目1112 求次数
- 移植usb-modeswitch-2.4.0到RT5350/MT7620原厂SDK
- 扫描一个网段内的可达ip
- JS数组与字符串相互转化
- 画图
- Activity的任务栈
- Eclipse中hibernate.cfg.xml配置文件加上自动提示功能
- [笔记]scanf的使用(主要是针对char)