hdu 4870

Rating

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Special Judge


Problem Description
A little girl loves programming competition very much. Recently, she has found a new kind of programming competition named "TopTopTopCoder". Every user who has registered in "TopTopTopCoder" system will have a rating, and the initial value of rating equals to zero. After the user participates in the contest held by "TopTopTopCoder", her/his rating will be updated depending on her/his rank. Supposing that her/his current rating is X, if her/his rank is between on 1-200 after contest, her/his rating will be min(X+50,1000). Her/His rating will be max(X-100,0) otherwise. To reach 1000 points as soon as possible, this little girl registered two accounts. She uses the account with less rating in each contest. The possibility of her rank between on 1 - 200 is P for every contest. Can you tell her how many contests she needs to participate in to make one of her account ratings reach 1000 points?
 

Input
There are several test cases. Each test case is a single line containing a float number P (0.3 <= P <= 1.0). The meaning of P is described above.
 

Output
You should output a float number for each test case, indicating the expected count of contest she needs to participate in. This problem is special judged. The relative error less than 1e-5 will be accepted.
 

Sample Input
  
  
1.000000 0.814700
 

Sample Output
  
  
39.000000 82.181160
 

解题思路:这道题目我一开始的想法是dp,可是又感觉状态方程无法保证无后效性,所以到这里就没有思路了。。。参考了别人的思路,确实感觉自己在这方面的题目做少了。

得分必须是f(0,0)->f(0,50)->f(50,50)->...->f(950,950)->f(950,1000)。所以所求期望次数就是到一个账号到1000的期望次数加上另一个账号达到950分的期望次数。记f(i)表示分数i*50到1000分需要的期望次数。那么答案ans=f(0)*2-f(19)。也就是说两次都到1000分,然后减去一次950到1000分的期望次数。

我们可以列方程,对于i>=2的数来说,我们记xi=f(i),那么可以得到方程组xi=p*(x(i+1)+1)+(1-p)*(x(i-2)+1)。其中(0<=i<20,i为0和1时需要特别处理,x20=0)。这样我们就可以直接套高斯消元法的模板了。

其实这道题目可以用递推去算,但是表示看不懂。。

这道题目给我的启发就是:有时候往往列出的状态方程却无法保证无后效性的时候,可以考虑把所有可能的状态都列出来(如果列出的方程组有唯一解),再利用高斯消元法把每个状态的值算出来即可,类似于这道递推的问题。


AC:

<span style="font-size:10px;">#include<iostream>
#include<cstring>
using namespace std;

const int maxn = 50;
const int eps = 1e-8;
double p,A[maxn][maxn];

void build_matrix()	//建立系数矩阵
{
	for(int i = 0; i < 20; i++)
	{
		if(i == 0) A[i][i] = p;
		else if(i == 1) A[i][0] = p-1;
		else A[i][i-2] = p-1;

		if(i != 19) A[i][i+1] = -p;
		if(i != 0) A[i][i] = 1;
		A[i][20] = 1;
	}
}

void Gauss(int n)
{
	int row = 0, col = 0,j,k,r;
	while(row < n && col < n) //处理第row个方程,第col个变量
	{
		r = row;
		for(k = row+1; k < n; k++)
		{
			if(fabs(A[k][col]) > fabs(A[row][col]))
				r = k;
		}
		if(fabs(A[r][col]) > eps)
		{
			if(r != col)
			{
				for(j = col; j <= n; j++)
					swap(A[r][j],A[row][j]);
			}
			for(k = row+1; k < n; k++)
			{
				double f = A[k][col]/A[row][col];
				for(j = col; j <= n; j++)
					A[k][j] -= f*A[row][j];
			}
			row++;
		}
		col++;
	}
	//回代求解过程
	for(k = n-1; k >= 0; k--)
	{
		for(j = k+1; j < n; j++)
			A[k][n] -= A[j][n]*A[k][j];
		A[k][n] /= A[k][k];
	}
	printf("%.6f\n",A[0][n]*2-A[19][n]);
}

int main()
{	
	while(cin>>p)
	{
		memset(A,0,sizeof(A));
		build_matrix();
		Gauss(20);
	}
	return 0;
}</span>



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值