一道求数学期望的dp,刚开始因为概率论没学好的缘故,连样例都看不懂……后来因为做了一道概率题,才明白了样例。做出来之后发现其实只是道水题……
先把连通分量都缩成一个点,然后就是简单的状压了。因为n到达30,数组开不下,所以我是用map实现状压的。
状态转移方程:dp[i][st]=(n-1)/(n-s)+sum{cnt[k]*dp[k][st^(1<<k)]/(n-s)}
k表示未访问过的节点,cnt[k]表示节点所代表的连通分量所含的原节点数,s表示当前已连的节点所含的原节点总数。
这题还有个trick,就是样例是错的,不是输出一位小数,而应该是6位浮点数。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
using namespace std;
vector<int> g[35];
int vis[35],cnt[35];
int n,m,e;
map<int,double> d[35];
void dfs(int u)
{
vis[u]=1;
cnt[e]++;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(!vis[v]) dfs(v);
}
}
int bitcount(int x)
{
int sum=0;
for(int i=0;i<e;i++) if(x&(1<<i))
sum+=cnt[i];