您的位置:首页 > 其它

hdu4576 Robot (概率DP)

2015-08-06 09:51 204 查看
比较简单的概率DP,也是场上出的第一道概率DP题,感觉和普通DP没有什么本质上的区别,只不过是用来求概率的 。

所以需要注意的还是那么几个 : 定义顺序(阶段)、弄清每一个阶段要产生几个决策(决定了该阶段的概率)、当前最优解依赖于已经求出的部分最优解、具有相似的最优子结构(可能有点抽象,不过确实如此)、处理好边界条件 ect

值得一提的是该题必须用滚动数组,不然会超内存(第一次就超了),借此机会也让我终于深刻理解了紫书上讲解滚动数组的那一段话 。

由于每一次的最优解依赖的只是他上一层的最优解,所以再之前的解已经没用了,因此只要保存两维,将其他的解覆盖掉就行了。循环滚动两行的值,所以一叫滚动数组。

代码如下:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n, m, l ,r;
const int maxm=1000005;
const int maxn=205;
double dp[2][maxn];
int a[maxm];
int main(){
    while(~scanf("%d%d%d%d", &n, &m, &l, &r) && m+n+l+r){
        for(int i =1; i<=m;++i) scanf("%d", &a[i]);
        memset(dp, 0, sizeof(dp)); //初始化边界,除了d[0][1] = 1; 其他都是 0 
        dp[0][1] = 1;
        int u=0;
        for(int i =1; i<=m;++i){
            u ^= 1;
            for(int j=1; j<=n;++j){
                dp[u][j]=0;
                int right=(j+a[i]);
                while(right>n) right-=n;
                int left=(j-a[i]);
                while(left<=0) left+=n;
                dp[u][j]+=(dp[1-u][left]/2);
                dp[u][j]+=(dp[1-u][right]/2);
            }
        }
        double pp=0;
        for(int i=l;i<=r;++i){
            pp+=dp[m%2][i];
        }
        printf("%.4f\n", pp);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: