题目:http://acm.hdu.edu.cn/showproblem.php?pid=4089
AC代码(C++):
#include <iostream> #include <queue> #include <vector> #include <set> #include <string> #include <algorithm> #include <cstdio> #include <cstring> #include <cmath> #define INF 0x3f3f3f3f #define eps 1e-5 typedef unsigned long long ull; typedef long long ll; typedef __int64 I64d; using namespace std; int n, m, k; double p1, p2, p3, p4; double dp[2005][2005]; int main() { while (cin >> n >> m >> k >> p1 >> p2 >> p3 >> p4) { if (p4 < eps) { cout << "0.00000" << endl; continue; } double p01 = p2 / (1 - p1); double p02 = p3 / (1 - p1); double p03 = p4 / (1 - p1); dp[1][1] = p03 / (1 - p01); for (int i = 2; i <= n; i++) { dp[i][i] = 0; dp[i][i] += pow(p01, i - 1)*p03; for (int j = 2; j <= k&&j <= i; j++)dp[i][i] += pow(p01, i - j) * (p02*dp[i - 1][j - 1] + p03); for (int j = k + 1; j <= i; j++)dp[i][i] += pow(p01, i - j)*p02*dp[i - 1][j - 1]; dp[i][i] /= (1 - pow(p01, i)); dp[i][1] = p01*dp[i][i] + p03; for (int j = 2; j <= k&&j < i; j++)dp[i][j] = p01*dp[i][j - 1] + p02*dp[i - 1][j - 1] + p03; for (int j = k + 1; j < i; j++)dp[i][j] = p01*dp[i][j - 1] + p02*dp[i - 1][j - 1]; } printf("%.5lf\n", dp[n][m]); } //system("pause"); }总结: 动态规划, 这类带环的表达式要通过化简和迭代(即先求出dp[i][i])来做. 这题有个坑, 算了多余的j不但会答案错误, 还会超内存.