首页 > 代码库 > POJ 3744 Scout YYF I (概率DP+矩阵快速幂)
POJ 3744 Scout YYF I (概率DP+矩阵快速幂)
题目地址:POJ 3744
一个线性概率DP递推式。dp[i]=p*dp[i-1]+p*dp[i-2]。但是i的值太大。所以可以分成n次,每一次中间过程的纯递推过程用矩阵快速幂来优化。只要想到矩阵快速幂就挺简单了。
代码如下:
#include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include <stdio.h> using namespace std; #define LL __int64 #define pi acos(-1.0) const int mod=100000000; const int INF=0x3f3f3f3f; const double eqs=1e-8; int a[20]; double dp[20]; struct Matrix { double ma[3][3]; }init, res; Matrix Mult(Matrix f1, Matrix f2) { int i, j, k; Matrix tmp; memset(tmp.ma,0,sizeof(tmp.ma)); for(i=0;i<2;i++){ for(j=0;j<2;j++){ tmp.ma[i][j]=0; for(k=0;k<2;k++){ tmp.ma[i][j]+=f1.ma[i][k]*f2.ma[k][j]; } } } return tmp; } Matrix Pow(Matrix x, int k) { Matrix tmp; int i, j; for(i=0;i<2;i++) for(j=0;j<2;j++) tmp.ma[i][j]=(i==j); while(k){ if(k&1) tmp=Mult(tmp,x); x=Mult(x,x); k>>=1; } return tmp; } int main() { int n, i, flag, k; double p, p1, p2; while(scanf("%d%lf",&n,&p)!=EOF){ for(i=1;i<=n;i++){ scanf("%d",&a[i]); } a[0]=0; sort(a,a+n+1); flag=0; for(i=1;i<=n;i++){ if(a[i]==a[i-1]+1||a[i]==1){ flag=1; break; } } if(flag){ printf("0.0000000\n"); continue ; } init.ma[0][0]=p;init.ma[0][1]=1-p; init.ma[1][0]=1;init.ma[1][1]=0; p1=1; for(i=1;i<=n;i++){ if(a[i]-a[i-1]==2){ p1=p1*(1-p); } else{ p2=p1*p; k=a[i]-a[i-1]-3; res=Pow(init,k); p1=(p2*res.ma[0][0]+p1*res.ma[0][1])*(1-p); //printf("k--%d\n",k); } //printf("%.7f\n",p1); } printf("%.7f\n",p1); } return 0; }
POJ 3744 Scout YYF I (概率DP+矩阵快速幂)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。