题目大意:有$m$个人要从城市$1$开始,依次游览城市$1$到$n$。

每一天,每一个游客有$p_i$的概率去下一个城市,和$1-p_i$的概率结束游览。

当游客到达城市$j$,他会得到$(1+\frac{C_j}{C_{j-1}})H_{i,j}$的收益,其中$C_i$表示到访第$i$个城市的人数。

问所有人的期望收益。

数据范围:$n,m≤16$

我们考虑状压$DP$

设$f[i][S]$表示到达城市i的人群为$S$的概率。

设$ans[i][S]$表示到达城市i的人群为$S$时,所有人在前$i$座城市的收益和。

不难推出:

$f[i][S]=\sum\limits_{S∈P} f[i-1][P]\times chg(P,S)$

$ans[i][S]=\sum\limits_{S∈P} \big(ans[i-1][P]+f[i-1][P]\times sum[i][S]\times (1+\frac{|S|}{|P|})\big)\times chg(P,S)$

其中,$chg(P,S)$表示前一次游览的人群为$P$,下一次剩下$S$的概率。简单乘一下就行了。

这么转移的复杂度是$O(n\times 3^m)$的,然而他T了。。。。

 #include<bits/stdc++.h>
#define M 16
#define get orzmyh
using namespace std; int m,n,all=; double p[M+]={},h[M+][M+]={},mulp[<<M]={},fmulp[<<M]={};
double f[M+][<<M]={},ans[M+][<<M]={},mo[<<M]={},sum[M+][<<M]={}; double Get(int P,int S){
return mulp[P&S]*fmulp[P^S];
}
double Sum(int day,int S){
double res=;
for(int i=;i<m;i++) if((<<i)&S){
res+=h[i][day];
}
return res;
} int main(){
scanf("%d%d",&m,&n); all=(<<m);
for(int i=;i<all;i++) mo[i]=mo[i>>]+(i&);
for(int i=;i<m;i++) scanf("%lf",p+i); for(int i=;i<all;i++){
double mul1=,mul2=;
for(int j=;j<m;j++)
if(i&(<<j)){
mul1=mul1*p[j];
mul2=mul2*(-p[j]);
}
mulp[i]=mul1;
fmulp[i]=mul2;
} for(int i=;i<m;i++)
for(int j=;j<=n;j++)
scanf("%lf",&h[i][j]); for(int i=;i<=n;i++){
for(int S=;S<all;S++)
sum[i][S]=Sum(i,S);
}
f[][all-]=; ans[][all-]=sum[][all-];
for(int i=;i<=n;i++){
for(int P=;P<all;P++)
for(int S=P;~S;S=P&(S-)){
double val=Get(S,P);
f[i][S]+=f[i-][P]*val;
ans[i][S]+=(ans[i-][P]+(mo[P]?sum[i][S]*(+mo[S]/mo[P])*f[i-][P]:))*val;
if(S==) break;
}
}
double Ans=;
for(int S=;S<all;S++)
Ans+=ans[n][S];
printf("%.10lf\n",Ans);
}

于是我后来写了一个$O(nm\times 2^m)$的,代码如下:

 #include<bits/stdc++.h>
#define M 17
using namespace std; double f[M][M]={},h[M][M]={},p[M]={};
int n,m; int main(){
scanf("%d%d",&m,&n);
for(int i=;i<=m;i++) scanf("%lf",p+i);
for(int i=;i<=m;i++){
f[i][]=;
for(int j=;j<=n;j++)
f[i][j]=f[i][j-]*p[i];
}
double ans=;
for(int i=;i<=m;i++){
for(int j=;j<=n;j++){
scanf("%lf",&h[i][j]);
ans+=f[i][j]*h[i][j];
}
}
for(int i=;i<n;i++){
for(int s=;s<(<<m);s++){
double ps=,sum=,pn=; int cnt=;
for(int j=;j<=m;j++) if(s&(<<(j-))){
ps*=f[j][i];
cnt++;
pn+=p[j];
}else ps*=-f[j][i]; for(int j=;j<=m;j++) if(s&(<<(j-)))
sum+=p[j]*h[j][i+]*(pn-p[j]+);
ans+=ps*sum/cnt;
}
}
printf("%.10lf\n",ans);
}

【xsy1596】旅行 期望+状压DP的更多相关文章

  1. 2018.09.23 bzoj1076: [SCOI2008]奖励关(期望+状压dp)

    传送门 一道神奇的期望状压dp. 用f[i][j]f[i][j]f[i][j]表示目前在第i轮已选取物品状态为j,从现在到第k轮能得到的最大贡献. 如果我们从前向后推有可能会遇到不合法的情况. 所以我 ...

  2. “景驰科技杯”2018年华南理工大学程序设计竞赛 A. 欧洲爆破(思维+期望+状压DP)

    题目链接:https://www.nowcoder.com/acm/contest/94/A 题意:在一个二维平面上有 n 个炸弹,每个炸弹有一个坐标和爆炸半径,引爆它之后在其半径范围内的炸弹也会爆炸 ...

  3. BZOJ3925: [Zjoi2015]地震后的幻想乡【概率期望+状压DP】

    Description 傲娇少女幽香是一个很萌很萌的妹子,而且她非常非常地有爱心,很喜欢为幻想乡的人们做一些自己力所能及的事情来帮助他们. 这不,幻想乡突然发生了地震,所有的道路都崩塌了.现在的首要任 ...

  4. BZOJ5006 THUWC2017随机二分图(概率期望+状压dp)

    下称0类为单边,1类为互生边,2类为互斥边.对于一种匹配方案,考虑其出现的概率*2n后对答案的贡献,初始为1,如果有互斥边显然变为0,否则每有一对互生边其贡献*2.于是有一个显然的dp,即设f[S1] ...

  5. 状压DP小拼盘

    有的DP题,某一部分的状态只有两种,选或不选. 开数组记录,代价太大,转移不方便. 状态压缩意为,用 “0/1“ 表示 “选/不选“ . 把状态表示为二进制整数. There are 10 kinds ...

  6. 【BZOJ】1076 [SCOI2008]奖励关 期望DP+状压DP

    [题意]n种宝物,k关游戏,每关游戏给出一种宝物,可捡可不捡.每种宝物有一个价值(有负数).每个宝物有前提宝物列表,必须在前面的关卡取得列表宝物才能捡起这个宝物,求期望收益.k<=100,n&l ...

  7. BZOJ1076 [SCOI2008]奖励关 【状压dp + 数学期望】

    1076: [SCOI2008]奖励关 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 3074  Solved: 1599 [Submit][Sta ...

  8. Problem Arrangement ZOJ - 3777(状压dp + 期望)

    ZOJ - 3777 就是一个入门状压dp期望 dp[i][j] 当前状态为i,分数为j时的情况数然后看代码 有注释 #include <iostream> #include <cs ...

  9. [思路题][LOJ2290][THUWC2017]随机二分图:状压DP+期望DP

    分析 考虑状压DP,令\(f[sta]\)表示已匹配状态是\(sta\)(\(0\)代表已匹配)时完美匹配的期望数量,显然\(f[0]=1\). 一条边出现了不代表它一定在完美匹配内,这也导致很难去直 ...

随机推荐

  1. nodejs 箭头函数

    背景 箭头函数,出现于ES6规范中. 使用 就是lambda函数. 一般使用: (a, b) => { return a + b; } 简略模式: 当参数只有一个时,可以省略括号:当返回值只有一 ...

  2. Failed to decode downloaded font

    碰到如下错误,该错误是开启layui的打印.导出.筛选列时出现的,不能正常显示图标及文字 原因: @参考文章 因为经过maven的filter,会破坏font文件的二进制文件格式,到时前台解析出错 解 ...

  3. [leetcode]80. Remove Duplicates from Sorted Array II有序数组去重(单个元素可出现两次)

    Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twic ...

  4. Android自定义View之上拉、下拉列表 头部元素跟随 缩放、平移效果的实现

    滑动ListView列表然后 listView上边的视图 跟随着上拉或者下拉的距离 自动放大或者缩小  视图里边元素自动平移的效果 思路很简单 根据listView 的滑动距离去计算图片和文字应该平移 ...

  5. 异常解决 Unable to write generated Java files for schemas: null

    错误是在使用cxf调用其他系统接口时报出的.而且问题很诡异,只有服务器调用时才报错,本地直接写main方法直接调用却正常的.以下是异常的堆栈: ERROR c.k.p.webservice.WebSe ...

  6. 回溯算法_ BackTracking

     目前还存在的疑问: 1. 所谓的该分支满足条件之后就回退到上一层节点,可是加谁呢? x[i+1]  ?? 加到 N, 不满足target sum条件就返回上一级(同时改变上一级数为 i+1...纵向 ...

  7. zabbix邮件自动预警

    Zabbix报警 自定义脚本报警 报警大致过程 item数据采集--->触发器由阈值触发带级别的信息-->触发动作发送邮件预警 1. 发送邮件脚本 1)安装sendEmail(参考Linu ...

  8. windows下mysql安装(zip包方式)

    1.安装地址 https://dev.mysql.com/downloads/mysql/ 2. 解压MySQL压缩包 发现并没有my-default.ini 配置文件主要的作用是设置编码字符集.安装 ...

  9. rsyslog和logrotate

    简介 rsyslog 是一个 syslogd 的多线程增强版. 现在Fedora和Ubuntu, rhel6默认的日志系统都是rsyslog了 rsyslog负责写入日志, logrotate负责备份 ...

  10. Tomcat架构解析(五)-----Tomcat的类加载机制

    类加载器就是根据类的全限定名(例如com.ty.xxx.xxx)来获取此类的二进制字节流的代码模块,从而程序可以自己去获取到相关的类. 一.java中的类加载器   1.类加载器类别 java中的类加 ...