POJ-3744 Scout YYF I 概率DP

  题目链接:http://poj.org/problem?id=3744

  简单的概率DP,分段处理,遇到mine特殊处理。f[i]=f[i-1]*p+f[i-2]*(1-p),i!=w+1,w为mine点。这个概率显然是收敛的,可以转化为(f[i]-f[i-1])/(f[i-1]-f[i-2])=p-1。题目要求精度为1e-7,在分段求的时候我们完全可以控制进度,精度超出了1e-7就不运算下去了。当然此题还可以用矩阵乘法来优化。

  考虑概率收敛代码:

 1 //STATUS:C++_AC_0MS_164KB

 2 #include <functional>

 3 #include <algorithm>

 4 #include <iostream>

 5 //#include <ext/rope>

 6 #include <fstream>

 7 #include <sstream>

 8 #include <iomanip>

 9 #include <numeric>

10 #include <cstring>

11 #include <cassert>

12 #include <cstdio>

13 #include <string>

14 #include <vector>

15 #include <bitset>

16 #include <queue>

17 #include <stack>

18 #include <cmath>

19 #include <ctime>

20 #include <list>

21 #include <set>

22 #include <map>

23 using namespace std;

24 //#pragma comment(linker,"/STACK:102400000,102400000")

25 //using namespace __gnu_cxx;

26 //define

27 #define pii pair<int,int>

28 #define mem(a,b) memset(a,b,sizeof(a))

29 #define lson l,mid,rt<<1

30 #define rson mid+1,r,rt<<1|1

31 #define PI acos(-1.0)

32 //typedef

33 typedef __int64 LL;

34 typedef unsigned __int64 ULL;

35 //const

36 const int N=200010;

37 const int INF=0x3f3f3f3f;

38 const int MOD=10007,STA=8000010;

39 const LL LNF=1LL<<55;

40 const double EPS=1e-14;

41 const double OO=1e30;

42 const int dx[4]={-1,0,1,0};

43 const int dy[4]={0,1,0,-1};

44 const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

45 //Daily Use ...

46 inline int sign(double x){return (x>EPS)-(x<-EPS);}

47 template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}

48 template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}

49 template<class T> inline T lcm(T a,T b,T d){return a/d*b;}

50 template<class T> inline T Min(T a,T b){return a<b?a:b;}

51 template<class T> inline T Max(T a,T b){return a>b?a:b;}

52 template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}

53 template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}

54 template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}

55 template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}

56 //End

57 

58 double f1,f2,f3;

59 double p;

60 int n;

61 

62 int main(){

63  //   freopen("in.txt","r",stdin);

64     int i,j,w[12],ok;

65     while(~scanf("%d%lf",&n,&p)){

66         f1=0;f2=1;

67         ok=1;

68         for(i=0;i<n;i++)scanf("%d",&w[i]);

69         sort(w,w+n);

70         for(i=1,j=0;j<n;j++){

71             if(w[j]==i)ok=0;

72             for(;i<w[j]-1 && sign(f2-f1);i++){

73                 f3=f2*p+f1*(1-p);

74                 f1=f2,f2=f3;

75             }

76             i=w[j]+1;

77             f2*=1-p;

78             f1=0;

79         }

80         printf("%.7lf\n",ok?f2:0.0);

81     }

82     return 0;

83 }

  

  矩阵乘法优化:

  1 //STATUS:C++_AC_16MS_164KB

  2 #include <functional>

  3 #include <algorithm>

  4 #include <iostream>

  5 //#include <ext/rope>

  6 #include <fstream>

  7 #include <sstream>

  8 #include <iomanip>

  9 #include <numeric>

 10 #include <cstring>

 11 #include <cassert>

 12 #include <cstdio>

 13 #include <string>

 14 #include <vector>

 15 #include <bitset>

 16 #include <queue>

 17 #include <stack>

 18 #include <cmath>

 19 #include <ctime>

 20 #include <list>

 21 #include <set>

 22 #include <map>

 23 using namespace std;

 24 //#pragma comment(linker,"/STACK:102400000,102400000")

 25 //using namespace __gnu_cxx;

 26 //define

 27 #define pii pair<int,int>

 28 #define mem(a,b) memset(a,b,sizeof(a))

 29 #define lson l,mid,rt<<1

 30 #define rson mid+1,r,rt<<1|1

 31 #define PI acos(-1.0)

 32 //typedef

 33 typedef __int64 LL;

 34 typedef unsigned __int64 ULL;

 35 //const

 36 const int N=200010;

 37 const int INF=0x3f3f3f3f;

 38 const int MOD=10007,STA=8000010;

 39 const LL LNF=1LL<<55;

 40 const double EPS=1e-14;

 41 const double OO=1e30;

 42 const int dx[4]={-1,0,1,0};

 43 const int dy[4]={0,1,0,-1};

 44 const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

 45 //Daily Use ...

 46 inline int sign(double x){return (x>EPS)-(x<-EPS);}

 47 template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}

 48 template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}

 49 template<class T> inline T lcm(T a,T b,T d){return a/d*b;}

 50 template<class T> inline T Min(T a,T b){return a<b?a:b;}

 51 template<class T> inline T Max(T a,T b){return a>b?a:b;}

 52 template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}

 53 template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}

 54 template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}

 55 template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}

 56 //End

 57 

 58 double p;

 59 int n;

 60 

 61 const int size=2;

 62 

 63 struct Matrix{

 64     double ma[size][size];

 65     Matrix friend operator * (const Matrix a,const Matrix b){

 66         Matrix ret;

 67         mem(ret.ma,0);

 68         int i,j,k;

 69         for(i=0;i<size;i++)

 70             for(j=0;j<size;j++)

 71                 for(k=0;k<size;k++)

 72                     ret.ma[i][j]=ret.ma[i][j]+a.ma[i][k]*b.ma[k][j];

 73         return ret;

 74     }

 75 }A;

 76 

 77 Matrix mutilpow(int k)

 78 {

 79     int i,j;

 80     Matrix ret;

 81     mem(ret.ma,0);

 82     for(i=0;i<size;i++)

 83         ret.ma[i][i]=1;

 84     for(;k;k>>=1){

 85         if(k&1)ret=ret*A;

 86         A=A*A;

 87     }

 88     return ret;

 89 }

 90 

 91 int main(){

 92  //   freopen("in.txt","r",stdin);

 93     int i,j,w[12],ok;

 94     Matrix S,t;

 95     double F[2];

 96     while(~scanf("%d%lf",&n,&p)){

 97         S.ma[0][0]=0,S.ma[0][1]=1;

 98         S.ma[1][0]=1-p,S.ma[1][1]=p;

 99         F[0]=0,F[1]=1;

100         ok=1;

101         for(i=0;i<n;i++)

102             scanf("%d",&w[i]);

103         sort(w,w+n);

104         for(i=0,j=1;i<n;i++){

105             if(w[i]==j){ok=0;break;}

106             A=S;

107             t=mutilpow(w[i]-j-1);

108             F[1]=(t.ma[1][0]*F[0]+t.ma[1][1]*F[1])*(1-p);

109             F[0]=0;

110             j=w[i]+1;

111         }

112 

113         printf("%.7lf\n",ok?F[1]:0.0);

114     }

115     return 0;

116 }

 

你可能感兴趣的:(poj)