BUPT2017 wintertraining(15) #5B

HDU - 4936

2014 Multi-University Training Contest 7 F

题意

直接看官方的题意和题解吧(来自:2014年多校的题解博客)。

题解

官方的不够细,我再梳理一下吧。

预处理:

首先dfs出所有可能的联通块状态,这个状态只考虑共几个联通块,每个联通块里几个岛,不考虑是哪些岛。然后对每个状态hash一下,编个号。根据我们dfs的顺序,1号状态是全部独立,cnt号状态是全部联通。

\(mg[i][x][y]\)为合并i状态的第x和第y个联通块得到的状态编号,可以求出来。

dp

我用\(dp[i][j]\)保存第i号状态,人在第j个岛上,到达目标的期望步数。

那么\(dp[1][1]\)就是答案,\(dp[cnt][i]\)都是0。

然后两种转移就是

1. 状态不变,i状态的j岛转移到v岛

步数就是\(dp[i][v]+1\)。

到达v岛的概率是\(\frac 1 {s_j}\)

如果产生了彩虹(p[j]),那么必须是连接同一联通块的岛。

a[i]是第i个联通块的岛的数量,\(C_{a[i]}^2\)种方案是不改变状态的,总方案是\(C_{n}^{2}\),于是彩虹连接同一联通块的概率就是\(\frac {\sum {a[i]*(a[i]-1)}}{n*(n-1)}\)。

否则不产生彩虹(1-p[j]),状态一定不变。

2. 状态改变,i状态的j岛转移到k状态的v岛

步数是\(dp[k][v]+1\)。

把步数乘上对应概率加起来就是期望值。

高斯消元

然后我们列出了这样的式子

\[dp[i][j]=\sum_{v\in s[j]}[(dp[i][v]+1)\cdot 概率]+\sum_{v\in s[j]}[(dp[k][v]+1)\cdot 概率]
\]

变形一下就是

\[dp[i][j]-\sum_{v\in s[j]} dp[i][v]\cdot\frac 1 {s_j} \cdot \left[p[j]\cdot \frac {\sum {a[i]\cdot (a[i]-1)}}{n\cdot(n-1)}+(1-p[j])\right]\\
=1+\sum_{\substack{v \in s[j]\\k=mg[i][x][y]}} dp[k][v]\cdot\frac 1 {s_j} \cdot \frac{a[x]\cdot a[y]}{(n\cdot (n-1)/2)}
\]

右边的dp是已经求得的,所以是个常数。左边的dp[i][j]作为未知数,j从1到n有n个这样的方程,n个未知数,可以高斯消元来求解。

ps. 这次的sb错,调了好一会儿:直接把整型数相乘然后去除以浮点数。另外这题好难啊,我想了很久,最后还是看官方题解加上看别人代码理解才写出来。

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#define N 22
#define M 1000007
using namespace std;
int cas,t,n,cnt,a[N];
int f[M+1],mg[700][N][N];
//f[code]:code对应的状态
//mg[s][x][y]:状态s的第x和第y个合并后的状态
double p[N],dp[700][N],g[N][N];
//dp[st][i],当前状态st,人在第i个岛上,到达目标状态的期望值
vector<int>s[N]; struct sta{
int a[N],tot;
}st[700]; int code(sta t){
int b=t.tot;
for(int i=1;i<=t.tot;i++)
b=(b*233%M+t.a[i])%M; //hash
return b;
}
void dfs(int d,int k,int sum){
if(sum==n){
sta &t=st[++cnt];
t.tot=d-1;
for(int i=1;i<d;i++)
t.a[i]=a[i];
f[code(t)]=cnt;
return;
}
for(int i=k;i<=n-sum;i++)
dfs(d+1,a[d]=i,sum+i);
}
int merge(sta t,int x,int y){
t.a[x]+=t.a[y];
swap(t.a[y],t.a[t.tot--]);
sort(t.a+1,t.a+t.tot+1);
return f[code(t)];
} void pre(){
//求出所有可能的状态并hash处理,求出合并两个联通块后对应的状态
cnt=0;
dfs(1,1,0);
for(int i=1;i<=cnt;i++)
for(int x=1;x<st[i].tot;x++)
for(int y=x+1;y<=st[i].tot;y++)
mg[i][x][y]=merge(st[i],x,y);
}
void gauss(double x[]){
for(int i=1;i<=n;i++){
int r=i;
while(!g[r][i]&&r<=n)r++;
if(r>n)return;
swap(g[r],g[i]);
for(int j=i+1;j<=n;j++){
double t=g[j][i]/g[r][i];
for(int k=1;k<=n+1;k++)
g[j][k]-=t*g[r][k];
}
}
for(int i=n;i;i--)if(g[i][i]){//注意判断
x[i]=g[i][n+1]/g[i][i];
for(int j=1;j<i;j++)
g[j][n+1]-=g[j][i]*x[i];
}
}
void work(){
memset(dp,0,sizeof dp);
for(int i=cnt-1;i>=1;i--){
memset(g,0,sizeof g);
for(int j=1;j<=n;j++){
double b=1;
for(int x=1;x<st[i].tot;x++)
for(int y=x+1;y<=st[i].tot;y++){
int k=mg[i][x][y];
double ps=p[j]*st[i].a[x]*st[i].a[y]/(n*(n-1)/2)/s[j].size();
for(int u=0;u<s[j].size();u++){
int v=s[j][u];
b+=dp[k][v]*ps;
}
}
g[j][j]=1;
g[j][n+1]=b;
double ps=0;
for(int x=1;x<=st[i].tot;x++)
ps+=st[i].a[x]*(st[i].a[x]-1);//连接同一联通块的岛的彩虹个数*2
ps/=n*(n-1);//除以 2*总的彩虹个数(n*(n-1)/2)
ps=(ps*p[j]+1-p[j])/s[j].size();
for(int u=0;u<s[j].size();u++){
int v=s[j][u];
g[j][v]-=ps;
}
}
gauss(dp[i]);
}
}
int main() {
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf",&p[i]),s[i].clear();
for(int i=1,t,v;i<=n;i++){
scanf("%d",&t);
while(t--){
scanf("%d",&v);
s[i].push_back(v);
}
}
pre();
work();
printf("Case #%d: %f\n",++cas,dp[1][1]);
}
return 0;
}

【 HDU 4936 】Rainbow Island (hash + 高斯消元)的更多相关文章

  1. HDU 5755 Gambler Bo(高斯消元)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5755 [题目大意] 一个n*m由0,1,2组成的矩阵,每次操作可以选取一个方格,使得它加上2之后对 ...

  2. HDU 4818 RP problem (高斯消元, 2013年长春区域赛F题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4818 深深地补一个坑~~~ 现场赛坑在这题了,TAT.... 今天把代码改了下,过掉了,TAT 很明显 ...

  3. ACM学习历程—HDU 3949 XOR(xor高斯消元)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3949 题目大意是给n个数,然后随便取几个数求xor和,求第k小的.(重复不计算) 首先想把所有xor的 ...

  4. hdu 5833 Zhu and 772002 高斯消元

    Zhu and 772002 Problem Description Zhu and 772002 are both good at math. One day, Zhu wants to test ...

  5. 2014多校第一场J题 || HDU 4870 Rating(DP || 高斯消元)

    题目链接 题意 :小女孩注册了两个比赛的帐号,初始分值都为0,每做一次比赛如果排名在前两百名,rating涨50,否则降100,告诉你她每次比赛在前两百名的概率p,如果她每次做题都用两个账号中分数低的 ...

  6. HDU 3571 N-dimensional Sphere(高斯消元 数论题)

    这道题算是比较综合的了,要用到扩展欧几里得,乘法二分,高斯消元. 看了题解才做出来orz 基本思路是这样,建一个n*(n-1)的行列式,然后高斯消元. 关键就是在建行列式时会暴long long,所以 ...

  7. HDU 3949 XOR ——线形基 高斯消元

    [题目分析] 异或空间的K小值. 高斯消元和动态维护线形基两种方法都试了试. 动态维护更好些,也更快(QAQ,我要高斯消元有何用) 高斯消元可以用来开拓视野. 注意0和-1的情况 [代码] 高斯消元 ...

  8. HDU 3949:XOR(高斯消元+线性基)

    题目链接 题意 给出n个数,问这些数的某些数xor后第k小的是谁. 思路 高斯消元求线性基. 学习地址 把每个数都拆成二进制,然后进行高斯消元,如果这个数字这一位(列)有1,那么让其他数都去异或它,消 ...

  9. HDU 3949 XOR [线性基|高斯消元]

    目录 题目链接 题解 代码 题目链接 HDU 3949 XOR 题解 hdu3949XOR 搞死消元找到一组线性无关组 消出对角矩阵后 对于k二进制拆分 对于每列只有有一个1的,显然可以用k的二进制数 ...

随机推荐

  1. Redis详解(六)------ RDB 持久化

     前面我们说过,Redis 相对于 Memcache 等其他的缓存产品,有一个比较明显的优势就是 Redis 不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,has ...

  2. Luogu4899 IOI2018 Werewolf 主席树、Kruskal重构树

    传送门 IOI强行交互可还行,我Luogu的代码要改很多才能交到UOJ去-- 发现问题是对边权做限制的连通块类问题,考虑\(Kruskal\)重构树进行解决. 对于图上的边\((u,v)(u<v ...

  3. BootStrap学习(2)_下拉菜单&按钮组

    一.下拉菜单 1.基本下拉菜单 如需使用下列菜单,只需要在class .dropdown 内加上下拉菜单即可.下面的实例演示了基本的下拉菜单: <!DOCTYPE html> <ht ...

  4. Linux性能评测工具之一:gprof篇

    这些天自己试着对项目作一些压力测试和性能优化,也对用过的测试工具作一些总结,并把相关的资料作一个汇总,以便以后信手拈来! 1 简介 改进应用程序的性能是一项非常耗时耗力的工作,但是究竟程序中是哪些函数 ...

  5. Hexo博客搭建以及Next主题美化的经验之谈

    这并不是一篇博客搭建教程.内容主要包含个人对于Hexo博客搭建的心得,Next6.0主题美化的部分建议,以及摘录一些各种用于博客搭建的link. 在博客园3年6个月,确实也学到了很多,博客园也是目前为 ...

  6. 记录:EM 算法估计混合高斯模型参数

    当概率模型依赖于无法观测的隐性变量时,使用普通的极大似然估计法无法估计出概率模型中参数.此时需要利用优化的极大似然估计:EM算法. 在这里我只是想要使用这个EM算法估计混合高斯模型中的参数.由于直观原 ...

  7. Linux系统下本地yum镜像源环境部署-完整记录

    之前介绍了Linux环境下本地yum源配置方法,不过这个是最简单最基础的配置,在yum安装的时候可能有些软件包不够齐全,下面说下完整yun镜像源系统环境部署记录(yum源更新脚本下载地址:https: ...

  8. 几何学观止(Riemann流形部分)

    上承这个页面,相较之前,增加了古典的曲线曲面论,这部分介绍得很扼要,Riemann流形介绍得也很快,花了仅仅30页就介绍到了Gauss-Bonnet公式.同时配上了提示完整的习题. 几何学观止-Rie ...

  9. VS2013软件的安装和单元测试

    VS2013是什么? 微软在Builder 2013开发者大会上发布了Visual Studio 2013预览版,并且发布其程序组件库.NET 4.5.1的预览版.该软件已于北京时间2013年11月1 ...

  10. Scrum Meeting NO.8

    Scrum Meeting No.8 1.会议内容 2.任务清单 徐越 序号 近期的任务 进行中 已完成 1 代码重构:前端通讯模块改为HttpClient+Json √ 2 添加对cookies的支 ...