hdu4576 Robot (概率DP)
2015-08-06 09:51
204 查看
比较简单的概率DP,也是场上出的第一道概率DP题,感觉和普通DP没有什么本质上的区别,只不过是用来求概率的 。
所以需要注意的还是那么几个 : 定义顺序(阶段)、弄清每一个阶段要产生几个决策(决定了该阶段的概率)、当前最优解依赖于已经求出的部分最优解、具有相似的最优子结构(可能有点抽象,不过确实如此)、处理好边界条件 ect
值得一提的是该题必须用滚动数组,不然会超内存(第一次就超了),借此机会也让我终于深刻理解了紫书上讲解滚动数组的那一段话 。
由于每一次的最优解依赖的只是他上一层的最优解,所以再之前的解已经没用了,因此只要保存两维,将其他的解覆盖掉就行了。循环滚动两行的值,所以一叫滚动数组。
代码如下:
所以需要注意的还是那么几个 : 定义顺序(阶段)、弄清每一个阶段要产生几个决策(决定了该阶段的概率)、当前最优解依赖于已经求出的部分最优解、具有相似的最优子结构(可能有点抽象,不过确实如此)、处理好边界条件 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; }
相关文章推荐
- 安装本地服务器
- hdu 3549 Flow Problem 【最大流】
- Centos php项目发布问题
- jquery时间轴
- php实现无限级分类(递归方法)
- Linux深入篇之一:配置Nginx Web服务器及多域名主机
- 初探单点登录 SSO
- 分类器之SVM学习
- C++11 标准新特性: 右值引用与转移语义
- 设计模式
- React with webpack
- Java开发实战经典 JDK6 带详细书签目录版
- 三张图片同时切换效果
- poj1273 Drainage Ditches(最大流)
- 南邮 OJ 1590 阶乘
- json传值乱码
- hdu3829 Cat VS Dog(二分最大独立集)
- 论数学中的无穷
- 国内CVPR和图像处理领域的公司和研究机构
- 构造函数和复制控制成员