问题

https://vjudge.net/problem/UVA-11600

分析

概率dp,看到了N<=30,想到了状态压缩,然后由于N比较大,而且状态中并不是所有状态都存在,所以使用map存储状态
对于M条边的处理,有两种办法,一种是用并查集,将连接起来的边连成一个集合,每次到下一个城市的时候,都去查看这个点的父节点和对应的 二进制的值(对应这个集合的所有点)
参考:https://www.cnblogs.com/jerryRey/p/4857941.html
或者将所有的联通点看作一个点,给这个点赋权,因为是多个点连接起来的,所以被访问的概率会比单独的点要大

状态转移方程 很明显 S是已走到的状态,k是从开始点能够联通的点的个数
d(S)代表现在状态是S,要全部联通的时间期望值
d(S)=k/(n−1)∗d(S)+1/(n−1)∗∑jd(S∣(1<<j))d(S)=k/(n-1)*d(S)+1/(n-1)*\sum_jd(S|(1<<j))d(S)=k/(n−1)∗d(S)+1/(n−1)∗∑j​d(S∣(1<<j)) 其中j不属于S
并查集:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
#include <unordered_map>
using namespace std;
typedef long long LL;
const int maxn=30+5;
int n,m,T,a,b,fa[maxn],digit[maxn];
unordered_map<int,double> dp;void init(){for(int i=0;i<n;++i){fa[i]=i;digit[i]=1<<i;}
}inline int findFa(int x){//路径压缩return (x==fa[x])?x:fa[x]=findFa(fa[x]);
}inline void unit(int x,int y){fa[x]=y;digit[y]|=digit[x];
}double dfs(int s){auto iter=dp.find(s);if(iter!=dp.end()) return iter->second;int k=0;double temp=0;for(int i=1;i<n;++i){if(!(s&(1<<i))){//digit[fa[i]]是i的联通集合temp+=dfs(s|digit[fa[i]]);}else ++k;}return dp[s]=(temp+n-1)/(n-1-k);
}int main(void){scanf("%d",&T);for(int t=1;t<=T;++t){scanf("%d%d",&n,&m);dp.clear();init();for(int i=0;i<m;++i){scanf("%d%d",&a,&b);int x=findFa(--a),y=findFa(--b);if(x!=y) unit(x,y);}//方便查询,这一步一定要和下面的dfs(digit[0])添加for(int i=0;i<n;++i) digit[i]=digit[findFa(i)];dp[(1<<n)-1]=0;//digit[0],确定初始化的集合double ans=dfs(digit[0]);printf("Case %d: %.7lf\n",t,ans);}return 0;
}

合并点,加权重:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
#include <unordered_map>
#include <vector>
using namespace std;
typedef long long LL;
const int maxn=30+5;
int n,m,T,a,b,nn,weight[maxn],vis[maxn];
unordered_map<int,double> dp;
vector<int> g[maxn];void init(){for(int i=0;i<=n;++i){g[i].clear();}memset(vis,0,sizeof(vis));memset(weight,0,sizeof(weight));
}int dfs_cnt(int u){int temp=1;vis[u]=1;for(int i=0;i<g[u].size();++i){if(vis[g[u][i]]) continue;temp+=dfs_cnt(g[u][i]);}return temp;
}double dfs(int s){auto iter=dp.find(s);if(iter!=dp.end()) return iter->second;int k=0;double temp=0;for(int i=0;i<nn;++i){if(!(s&(1<<i))){//digit[fa[i]]是i的联通集合temp+=weight[i]*dfs(s|(1<<i));}else k+=weight[i];}return dp[s]=(temp+n-1)/(n-k);
}int main(void){scanf("%d",&T);for(int t=1;t<=T;++t){scanf("%d%d",&n,&m);dp.clear();init();for(int i=0;i<m;++i){scanf("%d%d",&a,&b);--a; --b;g[a].push_back(b);g[b].push_back(a);}nn=0;for(int i=0;i<n;++i){if(!vis[i]){weight[nn++]=dfs_cnt(i);}}dp[(1<<nn)-1]=0;double ans=dfs(1);printf("Case %d: %.7lf\n",t,ans);}return 0;
}

UVA - 12235 Help Bubu 概率dp 状态压缩 记忆化搜索相关推荐

  1. 搜索问题之状态空间搜索(状态压缩+记忆化搜索+ BFS)

    文章目录 1. 前言 2. 问题举例(九宫格问题) 3. 问题分析 3.1 状态编码与解码 3.2 哈希映射 3.3 集合判重 4. 问题实现 推荐阅读 1. 前言 之前介绍的回溯法常用于 解空间的搜 ...

  2. UVA - 10253 Series-Parallel Networks(递推式、记忆化搜索写法)

    题目:UVA-10253 题目翻译(来自蓝书): 串并联网络有两个端点,一个叫源,一个叫汇,递归定义如下: (1) 一条单独的边是串并联网络. (2) 若G1和G2是串并联网络,把它们的源和源接在一起 ...

  3. 【DP】【记忆化搜索】NIKOLA(jzoj 1150)

    NIKOLA 题目大意: NIKOLA画了一排数字,他一开始在1,他可以往前跳T+1格(T为上一次跳到此格跳的格数),或往后T格(T一开始为0),但不能跳出界,没跳到一个格子,就要加上此格子的值(一开 ...

  4. 一个数变成0的概率有多少?(记忆化搜索)

    Description 给定一个数a0, 并给出定义:序列a1,a2,a3- 1.从闭区间[0,a0]中等概率随机选择一个整数k0,令a1=a0-k0 2.得到随机数a1后,再从闭区间[0,a1]中等 ...

  5. codeforces 424E Colored Jenga (状态压缩,概率dp用hash记忆优化搜索)

    题意: 给出以最多6层的积木,每层可以由三个木块拼成,总共有三种颜色的木块,开始时给出了积木的排列情况,我们每次可以从积木中抽一块木块,抽木块的规则是投骰子,骰子分别投到red,blue,green, ...

  6. LeetCode 464. 我能赢吗(状态压缩+记忆化递归 / 博弈)

    文章目录 1. 题目 2. 解题 1. 题目 在 "100 game" 这个游戏中,两名玩家轮流选择从 1 到 10 的任意整数,累计整数和,先使得累计整数和达到或超过 100 的 ...

  7. 【AcWing】数位统计DP、树形DP、状态压缩DP、记忆化搜索

    [AcWing]数位统计DP.树形DP.状态压缩DP.记忆化搜索 一.数位统计DP 二.状态压缩DP 三.树形DP 四.记忆化搜索 一.数位统计DP 计数问题 给定两个整数 a 和 b,求 a 和 b ...

  8. UVA - 11361 Investigating Div-Sum Property(数位dp/记忆化搜索板子)

    题目:https://vjudge.net/problem/UVA-11361 思路:数位dp,用记忆化搜索写,dp[pos][i][j][limit] 代表剩余有pos位,每位上的数字和模k 等于i ...

  9. 思维dp ---- Codeforces Round #711 (Div. 2) - C. Planar Reflections[dp/记忆化搜索]

    题目链接 题目大意: 就是给你n个平面和一个寿命为k的衰变粒子.开始粒子从左向右飞行,粒子每经过一个平面就会产生一个副本粒子,这个副本粒子比原粒子的寿命少1,即为k-1,并且飞行方向是原粒子的反方向. ...

  10. 【牛客练习赛13】 A B C D【康拓展开】 E【DP or 记忆化搜索】 F 【思维】

    A 幸运数字Ⅰ 链接:https://www.nowcoder.com/acm/contest/70/A 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K, ...

最新文章

  1. 提高网站页面收录的几个方法 返回列表 发新帖回复
  2. Android 工程报错解决 Unable to resolve target 'android-17'
  3. 读写分离数据库之MyCat
  4. 4.等待链表与调度链表
  5. 做组织机构树状图 spark
  6. json - 如何在 flutter 中的List String中加入2 json值?
  7. socket , 套接口还是套接字,傻傻分不清楚
  8. 使用.NET Core+Docker 开发微服务
  9. java 补充日期_Java 9对可选的补充
  10. 65 年来,全英国向他道歉三次,图灵,计算机人不能忘记的男人
  11. MapInfo启动时,提示the Microsoft jet engine is not available
  12. raspberry pi4B ncnn cpu vulkan benchmark
  13. bpsk调制及解调实验_【详解】5G的调制与解调
  14. 基于Web的酒店客房管理系统
  15. 2017-2018-1 20155314 20155323 实验二 固件程序设计
  16. 谈一谈CloudBlog的系统架构
  17. skyline三维地图与arcgis二维地图联动
  18. 使用Android Studio打包遇到的问题
  19. 通过快递鸟如何接入中通快递电子面单
  20. 盘点3种生涯的决策类型和方法,看看你是哪种类型?|【生涯荐读】

热门文章

  1. matlab 用循环求和,matlab求和不用循环
  2. 零基础学前端难吗?前端好学吗?
  3. 处理服务器恶意程序 kthreaddi挖矿
  4. word排版案例报告_Word操作技巧:图文混排,就是这么简单
  5. GNSS说第(四)讲---最新最全的IGS分析中心详情
  6. 中国脑计划颠覆性创新之路二,欧美脑计划存在重大缺陷
  7. ABB机器人与OMRON PLC Socket通信
  8. Unity3d编辑器的使用
  9. 洛谷 P2414 [NOI2011] 阿狸的打字机 题解
  10. ipad 邮箱服务器端口,ipad邮箱设置,牛排,YAHOO邮箱(后缀为yahoo