http://acm.hdu.edu.cn/showproblem.php?pid=5013

m个游客,n座城市(m, n <= 16), 每个人从1走到n, 每次有一定概率停在原地,然后以后就不前进了。一个人到过一个城会得到一定的愉悦度,对于相邻的两座城,会额外产生Cj / Cj - 1 * Hj的愉悦度,Cj是到过j城的人数,Hj是到过j城的人在这里获得的愉悦度之和。求期望的总愉悦度。

根据题解给出的解法

http://blog.csdn.net/oilover/article/details/39526899

需要跑3s左右

优化成纯dp能变成78ms,但是看不懂别人的代码...

根据期望的线性性,分别求每个人每天的值的期望



设f[i][j][x][y]表示第i天,前j个人,前一天x,当前天y的概率



设g[i][j][x][y]表示第i天,前j个人,前一天x,当前天y的期望



那么

f[i][j][x][y]=f[i][j-1][x][y]*(1-p[j]^(i-2))+f[i][j-1][x-1][y]*p[j]^(i-2)*(1-p[j])+f[i][j-1][x-1][y-1]*p[j]^(i-1)

g[i][j][x][y]=g[i][j-1][x][y]*(1-p[j]^(i-2))+g[i][j-1][x-1][y]*p[j]^(i-2)*(1-p[j])+(g[i][j-1][x-1][y-1]+f[i][j-1][x-1][y-1]*h[j][i])*p[j]^(i-1)

状态方程不懂,求各位大神解释..

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <iostream>
#include <algorithm>
using namespace std;
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define clr0(x) memset(x,0,sizeof(x))
typedef long long LL;
const int maxn = 20;
int n, m;
double p[maxn][maxn],h[maxn][maxn],f[maxn][maxn][maxn],g[maxn][maxn][maxn]; int main() {
while (~RD2(m,n)) {
for (int i = 1; i <= m; i++) {
scanf("%lf", &p[i][1]);
p[i][0] = 1.0;
for (int j = 2; j <= n; j++) {
p[i][j] = p[i][j - 1] * p[i][1];
}
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
scanf("%lf", &h[i][j]);
}
}
clr0(f),clr0(g); double ans = 0;
for (int i = 2; i <= n; i++) {
f[i][0][0] = 1;
for (int j = 1; j <= m; j++) {
for (int x = m; x >= 0; x--) {
for (int y = x; y >= 0; y--) {
f[i][x][y] *= (1.0 - p[j][i - 2]);
if (x > 0) {
f[i][x][y] += f[i][x - 1][y] * p[j][i - 2] * (1.0 - p[j][1]);
if (y > 0) {
f[i][x][y] += f[i][x - 1][y - 1] * p[j][i - 1];
}
}
g[i][x][y] *= (1.0 - p[j][i - 2]);
if (x > 0) {
g[i][x][y] += g[i][x - 1][y] * p[j][i - 2] * (1.0 - p[j][1]);
if (y > 0) {
g[i][x][y] += (g[i][x - 1][y - 1] + f[i][x - 1][y - 1] * h[j][i]) * p[j][i - 1];
}
}
}
}
}
for (int x = 1; x <= m; x++) {
for (int y = 1; y <= x; y++) {
ans += g[i][x][y] * ((double)y / x + 1.0);
}
}
}
for (int i = 1; i <= m; i++) {
ans += h[i][1];
}
printf("%.10f\n", ans);
} return 0;
}

hdu 5013 优化疑问+dp的更多相关文章

  1. fwt优化+树形DP HDU 5909

    //fwt优化+树形DP HDU 5909 //见官方题解 // BestCoder Round #88 http://bestcoder.hdu.edu.cn/ #include <bits/ ...

  2. 2017多校第4场 HDU 6078 Wavel Sequence DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6078 题意:求两个序列的公共波形子序列的个数. 解法: 类似于最长公共上升子序列,对于每个i,只考虑存 ...

  3. HDU 1011 树形背包(DP) Starship Troopers

    题目链接:  HDU 1011 树形背包(DP) Starship Troopers 题意:  地图中有一些房间, 每个房间有一定的bugs和得到brains的可能性值, 一个人带领m支军队从入口(房 ...

  4. 队列优化和斜率优化的dp

    可以用队列优化或斜率优化的dp这一类的问题为 1D/1D一类问题 即状态数是O(n),决策数也是O(n) 单调队列优化 我们来看这样一个问题:一个含有n项的数列(n<=2000000),求出每一 ...

  5. hdu 2296 aC自动机+dp(得到价值最大的字符串)

    Ring Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  6. HDU 4778 状压DP

    一看就是状压,由于是类似博弈的游戏.游戏里的两人都是绝对聪明,那么先手的选择是能够确定最终局面的. 实际上是枚举最终局面情况,0代表是被Bob拿走的,1为Alice拿走的,当时Alice拿走且满足变换 ...

  7. HDOJ(HDU).3466 Dividing coins ( DP 01背包 无后效性的理解)

    HDOJ(HDU).3466 Dividing coins ( DP 01背包 无后效性的理解) 题意分析 要先排序,在做01背包,否则不满足无后效性,为什么呢? 等我理解了再补上. 代码总览 #in ...

  8. HDOJ(HDU).2546 饭卡(DP 01背包)

    HDOJ(HDU).2546 饭卡(DP 01背包) 题意分析 首先要对钱数小于5的时候特别处理,直接输出0.若钱数大于5,所有菜按价格排序,背包容量为钱数-5,对除去价格最贵的所有菜做01背包.因为 ...

  9. HDOJ(HDU).2602 Bone Collector (DP 01背包)

    HDOJ(HDU).2602 Bone Collector (DP 01背包) 题意分析 01背包的裸题 #include <iostream> #include <cstdio&g ...

随机推荐

  1. 8Q - 献给杭电五十周年校庆的礼物

    我不能参赛,就送给学校一个DOOM III球形大蛋糕吧.等一等,吃蛋糕之前先考大家一个问题:如果校长大人在蛋糕上切了N刀(校长刀法极好,每一刀都是一个绝对的平面),最多可以把这个球形蛋糕切成几块呢?  ...

  2. PAT 1011 A+B和C (15)(C++&JAVA&Python)

    1011 A+B和C (15)(15 分) 给定区间[-2^31^, 2^31^]内的3个整数A.B和C,请判断A+B是否大于C. 输入格式: 输入第1行给出正整数T(<=10),是测试用例的个 ...

  3. 为什么CPU的主频止步于4GHz?

    你对CPU的认识大概还停留在奔腾4年代吧……奔腾4最终止步于3.8GHz,原计划推出的4GHz奔腾4处理器也被胎死腹中.英特尔意识到处理器研发道路上走入了“唯主频论”的误区,2004年10月,英特尔总 ...

  4. ES6 中 let and const

    let 和 const 命令 let 命令 基本用法 ES6 新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. { let a = 10; v ...

  5. 写一个简单的C词法分析器

    写一个简单的C词法分析器 在写本文过程中,我参考了<词法分析器的实现>中的一些内容.这里我们主要讨论写一个C语言的词法分析器. 一.关键字 首先,C语言中关键字有: auto.break. ...

  6. 链接PDO

    header('Content-type:text/html;Charset=utf-8'); /** * 实例化PDO对象 */ // 1, 设置相关的参数 // 1.1 确定数据源 $dbms = ...

  7. Java 线程池 Executor 框架

    在Java中,可以通过new Thread 的方法来创建一个新的线程执行任务,但是线程的创建是非常耗时的,而且创建出来的新的线程都各自运行.缺乏统一的管理,这样的后果是可能导致创建过多的线程从而过度消 ...

  8. Maximum Subarray LT53

    Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...

  9. 数据分析处理库pandas及可视化库Matplotlib

    一.读取文件 1)读取文件内容 import pandas info = pandas.read_csv('1.csv',encoding='gbk') # 获取文件信息 print(info) pr ...

  10. 用python实现数学多元数学方程式计算

    题目:公鸡5元钱一只,母鸡3元钱一只,小鸡3只一块钱,其中公鸡,母鸡,小鸡都必须有,问公鸡,母鸡,小鸡各买多少只刚好凑足100元钱? 一:数学算术分析: x+y+z=100 5x+3y+z/3=100 ...