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

sdut2878----Circle

时间:2014-12-30 11:52:09      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:dp

Circle

Time Limit: 2000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

You have been given a circle from 0 to n?-?1. If you are currently at x, you will move to (x?-?1) mod n or (x?+?1) mod n with equal probability. Now we want to know the expected number of steps you need to reach x from 0.

输入

The first line contains one integer T — the number of test cases.
 
Each of the next T lines contains two integers n,?x (0??≤?x?<?n?≤?1000) as we mention above.

输出

For each test case. Print a single float number — the expected number of steps you need to reach x from 0. The figure is accurate to 4 decimal places.

示例输入

3
3 2
5 4
10 5

示例输出

2.0000
4.0000
25.0000

提示

 

来源

2014年山东省第五届ACM大学生程序设计竞赛

示例程序


用高消水过去的,设dp[i]表示在位置i时到达x的期望步数

dp[i] = 0.5*(dp[(i + 1)%n] + 1) + 0.5 * (dp[(i - 1) % n] + 1) ;


注意(i - 1) % n 可能是负的,要加个n然后取模

把方程整理下

2 * dp[i] - dp[(i + 1) % n] - dp[(i - 1) % n] = 2;

然后对0-(n-1)每个点建立方程

/*************************************************************************
    > File Name: sdut2878.cpp
    > Author: ALex
    > Mail: 405045132@qq.com 
    > Created Time: 2014年12月29日 星期一 22时00分21秒
 ************************************************************************/

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1010;
const double eps = 1e-12;

double mat[N][N], x[N];
bool free_x[N];
int n, e;

int Gauss()
{
	int free_index, free_num;
	int max_r, k, col, var, equ;
	var = equ = n;
	memset (free_x, 1, sizeof(free_x));
	memset (x, 0, sizeof(x));
	for (k = col = 0; k < equ && col < var; ++k, ++col)
	{
		max_r = k;
		for (int i = k + 1; i < equ; ++i)
		{
			if (fabs(mat[i][col]) - fabs(mat[max_r][col]) > eps)
			{
				max_r = i;
			}
		}
		if (max_r != k)
		{
			for (int j = k; j < var + 1; ++j)
			{
				swap(mat[max_r][j], mat[k][j]);
			}
		}
		if (fabs(mat[k][col]) <= eps)
		{
			--k;
			continue;
		}
		for (int i = k + 1; i < equ; ++i)
		{
			if (fabs(mat[i][col]) <= eps)
			{
				continue;
			}
			double tmp = mat[i][col] / mat[k][col];
			for (int j = col; j < var + 1; ++j)
			{
				mat[i][j] -= mat[k][j] * tmp;
			}
		}
	}
	for (int i = k; i < equ; ++i)
	{
		if (fabs(mat[i][var]) > eps)
		{
			return 0;
		}
	}
	if (k < var)
	{
		for (int i = k - 1; i >= 0; --i)
		{
			free_num = 0;
			for (int j = 0; j < var; ++j)
			{
				if (fabs(mat[i][j]) > eps && free_x[j])
				{
					free_num++;
					free_index = j;
				}
			}
			if (free_num > 1)
			{
				continue;
			}
			double tmp = mat[i][var];
			for (int j = 0; j < var; ++j)
			{
				if (j != free_index && fabs(mat[i][j]) > eps)
				{
					tmp -= mat[i][j] * x[j];
				}
			}
			free_x[free_index] = 0;
			x[free_index] = tmp / mat[i][free_index];
		}
		return var - k;
	}
	for (int i = var - 1; i >= 0; --i)
	{
		double tmp = mat[i][var];
		for (int j = i + 1; j < var; ++j)
		{
			if (fabs(mat[i][j]) > eps)
			{
				tmp -= x[j] * mat[i][j];
			}
		}
		x[i] = tmp / mat[i][i];
	}
	return 1;
}

int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
	{
		scanf("%d%d", &n, &e);
		memset (mat, 0, sizeof(mat));
		for (int i = 0; i < n; ++i)
		{
			if (i == e)
			{
				mat[i][i] = 1;
				mat[i][n] = 0;
			}
			else
			{
				mat[i][i] = 2;
				mat[i][(i + 1) % n] = -1;
				int t = (i - 1) % n;
				if (t < 0)
				{
					t = (t + n) % n;
				}
				mat[i][t] = -1;
				mat[i][n] = 2;
			}
		}
		Gauss();
		printf("%.4f\n", x[0]);
	}
	return 0;
}



sdut2878----Circle

标签:dp

原文地址:http://blog.csdn.net/guard_mine/article/details/42262651

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