Maximum Random Walk
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 756 Accepted Submission(s): 419
三维dp,一维的话根本没有办法开展,二维的话没办法保存当前位置或者最远位置,所以只能用三维的。
看不懂滚动数组之类的操作,只能傻傻的写。
具体内容在代码里标注了,三重循环,从i,j,k的状态递推它之后的状态。
在我看来,递推DP有两种,一种是从当前状态推出其他状态,一种是推导当前状态是怎么来的。
这个题只能写前者,因为如果写后者的话,K的更新比较麻烦,不好处理。
上一个题写后者就比较容易,还是得做题体会吧。。。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define mem(a,b) memset(a,b,sizeof(a)) 4 #define ll long long 5 #define inf 1000000000 6 #define maxn 300 7 #define maxm 100005 8 #define eps 1e-10 9 #define for0(i,n) for(int i=1;i<=(n);++i) 10 #define for1(i,n) for(int i=1;i<=(n);++i) 11 #define for2(i,x,y) for(int i=(x);i<=(y);++i) 12 #define for3(i,x,y) for(int i=(x);i>=(y);--i) 13 #define mod 1000000007 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();} 18 while(ch>='0'&&ch<='9') {x=10*x+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 float dp[101][201][201];//表示走了i步后到达j点b并且最远达到k的概率 22 //什么时候考虑这个状态向外发散,什么时候考虑这个状态由其他几个状态飞来 23 int main() 24 { 25 int T; 26 while(~scanf("%d",&T)) 27 { 28 for(int i=1;i<=T;++i) 29 { 30 int index=read(); 31 mem(dp,0); 32 printf("%d ",index); 33 int n=read(); 34 double pl,pr; 35 scanf("%lf%lf",&pl,&pr); 36 double pk=1-pl-pr; 37 dp[0][100][100]=1; 38 int l=100-n,r=100+n; 39 for(int j=0;j<n;++j)//考虑的是,从j,k,h走向下一步的所有可能 40 for(int k=l;k<=r;++k) 41 for(int h=100;h<=100+n;++h) 42 { 43 dp[j+1][k][h]+=dp[j][k][h]*pk; 44 dp[j+1][k-1][h]+=dp[j][k][h]*pl; 45 if(k+1>h) dp[j+1][k+1][k+1]+=dp[j][k][h]*pr; 46 else dp[j+1][k+1][h]+=dp[j][k][h]*pr; 47 } 48 double ans=0; 49 for(int j=l;j<=r;++j) 50 for(int k=100;k<=r;++k) 51 ans+=(k-100)*dp[n][j][k]; 52 printf("%.4lf\n",ans); 53 } 54 } 55 } 56