1. 程式人生 > >HDU 4487 Maximum Random Walk

HDU 4487 Maximum Random Walk

ted \n index col using bmi 一個 分享圖片 float

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

HDU 4487 Maximum Random Walk