码迷,mamicode.com
首页 > 其他好文 > 详细

2013ACM-ICPC杭州赛区全国邀请赛——Random Walk

时间:2014-05-09 22:53:59      阅读:422      评论:0      收藏:0      [点我收藏+]

标签:acm   dp   gauss消元   数学   

题目链接

  • 题意:
    n个点,按照题中给的公式可以求出任意两个点转移的概率。求从1到n的期望转移次数
  • 分析:
    设dp[i]为从i到n的期望,那么可以得到公式dp[i] = sigma(dp[i + j] * p(i + j, i)),1 <= j <= m
    把这个式子展开来:dp[i - m] * p(i - m, i) + dp[i - m + 1] * dp(i - m + 1, i) + ... + dp[i] * p(i, i) + ... + dp[i + m] * p(i + m, i) = dp[i]
    展开p(i, i),化简:dp[i - m] * p(i - m, i) + dp[i - m + 1] * dp(i - m + 1, i) + ... + dp[i] * p‘(i, i) + ... + dp[i + m] * p(i + m, i) = -1(注意p‘(i, i)和题目中有所不同了,等与p(i, i) - 1)
    其实这里也可以发现,题目中的p(i, i)给的还是比较有特点的,有一个常数1,这样在列方程的时候才可以消元使得方程右边是一个常数
    解方程的时候,首先注意dp[n] = 0,这个方程是不用解的。之后可以安装普通的gauss消元从上到下消元,再回代出结果;或者更简单的,题目只要求dp[1],那么如果从下到上求,最后直接除以系数即可

    也算是一个概率DP吧,比较关键的想法在于能将问题分解为n个状态,之后就可以用高斯消元来解决了
    高斯消元的分析时,应该注意到这个矩阵比较稀疏,且消元的时候,只需要考虑最多m行的m个位置即可,复杂度不是普通的O(n ^ 3),而是O(n * m * m)
double b[maxn];
double p[maxn][15];

int main()
{
	//    freopen("in.txt", "r", stdin);
	while (~RII(n, m) && n)
	{
		FE(i, 1, n) FE(j, 1, m)
			RI(c[i][j]);
		FF(i, 1, n)
		{
			double sum = 1, s = 0;
			FE(j, 1, m)
				sum += c[i][j];
			FE(j, 1, m)
			{
				if (i - j >= 1)
					s += p[i][m - j] = 0.3 * c[i][j] / sum;
				if (i + j <= n)
					s += p[i][m + j] = 0.7 * c[i][j] / sum;
			}
			p[i][m] = -s;
			b[i] = -1;
		}
		FED(i, n - 1, 1)
		{
			int l = max(1, i - m), r = min(n - 1, i + m);
			FF(j, l, i)
			{
				double f = p[j][m - j + i] / p[i][m];
				FE(k, l, r)
					p[j][m - j + k] -= p[i][m - i + k] * f;
				b[j] -= f * b[i];
			}
		}
		printf("%.2f\n", b[1] / p[1][m]);
	}
	return 0;
}


2013ACM-ICPC杭州赛区全国邀请赛——Random Walk,布布扣,bubuko.com

2013ACM-ICPC杭州赛区全国邀请赛——Random Walk

标签:acm   dp   gauss消元   数学   

原文地址:http://blog.csdn.net/wty__/article/details/25415585

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!