HDU 4579 Random Walk (解方程)
轉載請註明出處,謝謝http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
題意 :n個位置,每次可以向前走1-m步或者向後者1-m步,或者不動,概率都可以計算出來。問從1走到n的期望步數。
http://acm.hdu.edu.cn/showproblem.php?pid=4579
由於m非常小,只有5。所以用dp[i]表示從位置i出發到達n的期望步數。
那麼dp[n] = 0
dp[i] = sigma(dp[i + j] * p (i , i + j)) + 1 . (-m <= j <= m)
n個方程,n個變元,由於每個方程中的未知數不多,所以可以暴力消元。
每次的原則是以每個位置的方程,將高位全部消元,利用高位置的殘留方程。
比如說以位置 i的方程,保留dp[i] = a1 * dp[i - 1] + a2 * dp[i - 2] …… am * dp[i - m]。
最後的常數便是結果,注意細節,以及小心RE,問題不大。
O(n * m)的複雜度從大到小暴力消元。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
const int N = 50005;
double p[N][11];
int n , m , c[11];
int l[N] , r[N];
double a[N][11];
double constant[N];
bool zero (double d) {
const double eps = 1e-6;
return fabs(d) < eps;
}
int main () {
#ifndef ONLINE_JUDGE
freopen ("input.txt" , "r" , stdin);
#endif
while (scanf ("%d %d" , &n, &m) != EOF) {
if (!n & !m) break;
for (int i = 1 ; i <= n ; i ++) {
int tot = 0;
for (int j = 1 ; j <= m ; j ++) {
scanf ("%d" , &c[j]);
tot += c[j];
}
double other = 1.0;
for (int j = -m ; j < 0 ; j ++) {
p[i][j + m] = 0.3 * c[-j] / (1 + tot);
if (i + j >= 1) other -= p[i][j + m];
}
for (int j = 1 ; j <= m ; j ++) {
p[i][j + m] = 0.7 * c[j] / (1 + tot);
if(i + j <= n) other -= p[i][j + m];
}
p[i][m] = other;
}
memset (a , 0 , sizeof(a));
for (int i = n - 1 ; i > 0 ; i --) {
l[i] = max(i - m , 1);
r[i] = min(n , i + m);
for (int j = 0 ; j < r[i] - l[i] + 1 ; j ++) {
a[i][j] = p[i][(l[i] + j) - i + m];
}
constant[i] = 1.0;
for (int j = r[i] ; j > i ; j --) {
if (j == n) a[i][j - l[i]] = 0;
else {
double q = a[i][j - l[i]];
if (zero(q)) continue;
for (int k = 0 ; k < j - l[j] ; k ++) {
a[i][k + l[j] - l[i]] += a[j][k] * q;
}
a[i][j - l[i]] = 0;
constant[i] += constant[j] * q;
}
}
double q = 1 - a[i][i - l[i]];
for (int j = 0 ; j < r[i] - l[i] + 1 ; j ++) {
a[i][j] = a[i][j] / q;
}
a[i][i - l[i]] = 0;
constant[i] = constant[i] / q;
}
printf ("%.2f\n" , constant[1]);
}
return 0;
}
相關文章
- [論文閱讀筆記] Community aware random walk for network embedding筆記Unityrandom
- os.walk 和os.path.walk的區別
- xmlrpc walk throughXMLRPC
- matlab求解方程組Matlab
- Python(os.walk())Python
- ARC173D-Bracket Walk3DRacket
- 利用matlab求解方程和方程組Matlab
- Python中os.walk()模組Python
- random 模組random
- Random和Math.random()簡單總結random
- Interview-Harry Potter walk through matrix.View
- Math.random()random
- Math.randomrandom
- random()函式random函式
- dbms_randomrandom
- C語言實現牛頓迭代法解方程C語言
- python os.walk()和os.listdir()Python
- 【DBMS_RANDOM】使用 DBMS_RANDOM包生成隨機字串random隨機字串
- python random模組Pythonrandom
- np.random.choicerandom
- DBMS_RANDOM使用random
- 測試random類random
- 11 random案例1random
- Random 類的使用random
- different random numbers generatorrandom
- php中array_walk函式是什麼?PHP函式
- 使用github.com/lxn/walk建立桌面應用Github
- 圖形使用者介面1:初識Walk
- centos5.4 kernel random number generator_/dev/urandom及/dev/randomCentOSrandomdev
- np.random.multivariate_normal()randomORM
- numpy-random函式random函式
- python_random模組Pythonrandom
- JAVA的Random類(轉)Javarandom
- Scanner類、Random類、ArrayList類random
- python-random的用法Pythonrandom
- JAVA中的Random()函式Javarandom函式
- Java 8 中的 Random 類Javarandom
- Leetcode - Random Pick IndexLeetCoderandomIndex