hdu1437(概率DP)

天气情况

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 547    Accepted Submission(s): 220


Problem Description
如果我们把天气分为雨天,阴天和晴天3种,在给定各种天气之间转换的概率,例如雨天转换成雨天,阴天和晴天的概率分别为0.4,0.3,0.3.那么在雨天后的第二天出现雨天,阴天和晴天的概率分别为0.4,0.3,0.3.现在给你今天的天气情况,问你n天后的某种天气出现的概率.
 

Input
我们这里假设1,2,3分别代表3种天气情况,Pij表示从i天气转换到j天气的概率.
首先是一个数字T表示数据的组数.
每组数据以9个数开始分别是P11,P12,P13,……,P32,P33,接着下一行是一个数字m,表示提问的次数。每次提问有3个数据,i,j,n,表示过了n天从i天气情况到j天气情况(1<=i,j<=3 1<=n<=1000)。
 

Output
根据每次提问输出相应的概率(保留3位小数)。
 

Sample Input
   
   
   
   
1 0.4 0.3 0.3 0.2 0.5 0.3 0.1 0.3 0.6 3 1 1 1 2 3 1 1 1 2
 

Sample Output
   
   
   
   
0.400 0.300 0.250 Hint:如果GC提交不成功,可以换VC试试
 

Author
xhd
 

Source
ACM暑期集训队练习赛(四)
 

Recommend
lcy
 
本题给出不同天气每过一天之间转化的概率以及起始天气和终止天气和之间的天数,求概率。本题是个典型的概率DP,关键要找准状态转移方程。
设dp[i][j]为过了i天天气为j的概率,则状态转移方程为为:
           dp[i][1]=dp[i-1][i]*p[1][1]+dp[i-1][2]*p[2][1]+dp[i-1][3]*p[3][1]
           dp[i][2]=dp[i-1][1]*p[1][2]+dp[i-1][2]*p[2][2]+dp[i-1][3]*p[3][2]
           dp[i][3]=dp[i-1][1]*p[1][3]+dp[i-1][2]*p[2][3]+dp[i-1][3]*p[3][3]
为了加快速度,可以用矩阵的快速幂求解。
 
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;


//*****************************************************
//origin存放需计算的矩阵,res存放答案矩阵
//最终答案为res.a[1][0](对应f[n])
struct matrix
{
	double a[3][3];
};
matrix origin,res;

//将res初始化为初始条件矩阵,人为输入关系递推矩阵origin
void init()
{
	int i,j;
	for(i=0;i<3;i++)
	{
		for(j=0;j<3;j++)
		{
			scanf("%lf",&origin.a[j][i]);
		}
	}
}

//直接将2个矩阵相乘x*y,返回计算后的矩阵
matrix multiply(matrix &x,matrix &y)
{
	matrix temp;
	memset(temp.a,0,sizeof(temp.a));
	for(int i=0;i<3;i++)
	{
		for(int j=0;j<3;j++)
		{
			for(int k=0;k<3;k++)
			{
				temp.a[i][j]+=x.a[i][k]*y.a[k][j];
			}
		}
	}
	return temp;
}

//矩阵快速幂的计算,矩阵的n次幂,每个中间结果对MOD取模
void calc(matrix &origin,matrix &res,int n)
{
	while(n)
	{
		if(n&1)
			res=multiply(origin,res);
		n>>=1;
		origin=multiply(origin,origin);
	}
}
//*****************************************************

int main()
{
	int cas,i,n,query,s,e;
	cin>>cas;
	while(cas--)
	{
		init();
		matrix tmp=origin;
		scanf("%d",&query);
		while(query--)
		{
			scanf("%d%d%d",&s,&e,&n);
			memset(res.a,0,sizeof(res.a));
			s--,e--;
			res.a[s][0]=1;
			calc(origin,res,n);
			printf("%0.3lf\n",res.a[e][0]);
			origin=tmp;
		}
	}
	return 0;
}

你可能感兴趣的:(动态规划,矩阵的快速幂)