POJ 3744 Scout yyf I (probability DP + rapid matrix power)
Address: POJ 3744
A linear probability DP recursive formula. Dp [I] = p * dp [I-1] + (1-p) * dp [I-2]. However, the I value is too large. Therefore, it can be divided into n times, and the pure recursive process of each intermediate process is optimized by the matrix Rapid power. It is easy to think of the Rapid power of a matrix.
The Code is as follows:
#include
#include
#include
#include
#include #include
#include
#include
#include
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;}