CF482C Game with Strings (状压DP+期望DP)

题目大意:甲和乙玩游戏,甲给出n(n<=50)个等长的字符串(len<=20),然后甲选出其中一个字符串,乙随机询问该字符串某一位的字符(不会重复询问一个位置),求乙能确定该串是哪个字符串的询问次数的期望值

这题不看题解好难想......(感谢zhx和zhx两位大佬的题解)

len很小,考虑状压DP,显然我们要状压询问,要定义两个状态,f[]和num[]

1表示询问,0表示未询问

那么,我们定义f[s]表示询问状态s距离确定一个字符串所需要的期望值。

定义tot是s状态剩余的询问的次数,那么显然因为询问剩余的每一位的概率是相等的

而一个询问并不一定能确定唯一一个字符串,可能是好几个,所以我们要处理这个询问状态能确定几个字符串,即num[s]

而num[s]并不能通过暴力枚举得到,所以我们只能通过枚举它的父集来获取它的状态

我们把字符串两两匹配,定义为s状态不能确定的串(用二进制表示哪些串不能确定),接着我们从大到小枚举状态,每个子集都从它的父集更新,取所有的并集,其中1的数量即为num

tip1:而如果1的数量为1,该状态仍然可以确定所有的串,所以此时num是0

最后我们得到一个很玄学的方程

最后的f[0]即为答案

tip2:当n==1时,出题人貌似想告诉我们,因为不论问不问都只有一个串,所以不用问也知道是哪个......

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #define N 55
 5 #define maxn (1<<20)+100
 6 #define ll long long
 7 #define dd double
 8 #define seed 13131
 9 using namespace std;
10
11 int n,m;
12 char str[55][22];
13 dd f[maxn];
14 ll unidf[maxn];
15 int num[maxn];
16
17 int main()
18 {
19     //freopen("aa.in","r",stdin);
20     scanf("%d",&n);
21     if(n==1) {printf("0.0000000000\n");return 0;}
22     for(int i=0;i<n;i++)
23         scanf("%s",str[i]);
24     m=strlen(str[1]);
25     for(int i=0;i<n;i++)
26         for(int j=i+1;j<n;j++)
27         {
28             int pos=0;
29             for(int k=0;k<m;k++){
30                 if(str[i][k]==str[j][k])
31                    pos|=(1<<k);
32             }
33             unidf[pos]|=(1ll<<j)|(1ll<<i);
34         }
35     for(int s=(1<<m)-1;s>=0;s--)
36     {
37         for(int i=0;i<m;i++)
38             if(!(s&(1<<i))) unidf[s]|=unidf[s|(1<<i)];
39         for(int j=0;j<n;j++)
40             if(unidf[s]&(1ll<<j)) num[s]+=1;
41         if(num[s]==1) num[s]=0;
42     }
43     f[(1<<m)-1]=0;
44     for(int s=(1<<m)-2;s>=0;s--)
45     {
46         if(!num[s]) {f[s]=0;continue;}
47         int tot=0;
48         for(int i=0;i<m;i++) if(!(s&(1<<i)))tot++;
49         for(int i=0;i<m;i++)
50         {
51             if(((1<<i)&s)) continue;
52             f[s]+=(f[s|(1<<i)]/(dd)tot*(dd)num[s|(1<<i)]/(dd)num[s]);
53         }
54         f[s]+=1.0;
55     }
56     printf("%.10lf\n",max(f[0],1.00000000000));
57     return 0;
58 }

原文地址:https://www.cnblogs.com/guapisolo/p/9696978.html

时间: 2024-10-29 03:02:26

CF482C Game with Strings (状压DP+期望DP)的相关文章

HDU 4336 Card Collector(容斥原理 or 状压求期望dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4336 Problem Description In your childhood, do you crazy for collecting the beautiful cards in the snacks? They said that, for example, if you collect all the 108 people in the famous novel Water Margin,

UVA - 10817 Headmaster&#39;s Headache (状压类背包dp+三进制编码)

题目链接 题目大意:有S门课程,N名在职教师和M名求职者,每名在职教师或求职者都有自己能教的课程集合以及工资,要求花费尽量少的钱选择一些人,使得每门课程都有至少两人教.在职教师必须选. 可以把“每个课程已经分别有几个人教”作为状态来进行转移,每个人能教的课程集合作为“物品重量”,工资作为“价值”来更新dp值,类似01背包,每放进一个人,从后往前更新即可. 状态的表示可以用三进制编码,为了写起来舒服,我写了个结构体作为状态和编码转换的桥梁,也可以进行状态的“加法运算”,虽然速度比较慢就是了~~ 有

Codeforces 482C. Game with Strings 状压DP

很好的状压dp题目 d[mask]=x   在询问了mask位的情况下,有x状态的串还是不能区分 /// 预处理不好会TLE dp[x]  从一次也没有问,到问到状态x时的概率 可以看 http://blog.csdn.net/houserabbit/article/details/40658791 大神的题解 C. Game with Strings time limit per test 1 second memory limit per test 256 megabytes input s

Codeforces 544E Remembering Strings 状压dp

题目链接 题意: 给定n个长度均为m的字符串 下面n行给出字符串 下面n*m的矩阵表示把对应的字母修改成其他字母的花费. 问: 对于一个字符串,若它是easy to remembering 当 它存在一个字母,使得这个字母在这一列是独一无二的. 要使得n个字符串都是easy to remembering 的最小花费. 第一个样例是把第一列的4个a中3个a修改成别的字母,所以花费为3. 思路: 显然是个状压dp,但需要一点转化. 首先得到一个结论: 对于某一列,设这一列的字母是 a,a,b,b,a

HDU 4336-Card Collector(状压,概率dp)

题意: 有n种卡片,每包面里面,可能有一张卡片或没有,已知每种卡片在面里出现的概率,求获得n种卡片,需要吃面的包数的期望 分析: n很小,用状压,以前做状压时做过这道题,但概率怎么推的不清楚,现在看来就是基本的概率dp dp[s]表示获得卡片种数情况是s时期望包数,dp[(1<<n)-1]=0,dp[0]就是答案 dp[s]=sum(dp[s+(1<<j)]*p[j])+1+(1-tmp)*dp[s](tmp是未吃到的卡片的概率和) 移项化简即可 #include <map&

UVA 11600-Masud Rana(状压,概率dp)

题意: 有n个节点的图,开始有一些边存在,现在每天任意选择两点连一条边(可能已经连过),求使整个图联通的期望天数. 分析: 由于开始图可以看做几个连通分量,想到了以前做的一个题,一个点代表一个集合(这里是连通分量)进行压缩 dp[i][s]表示最后连接的第i个联通分量,联通状态是s时的期望天数,dp[0][1],即为答案,由于s可能很大,用记忆化搜索 #include <map> #include <set> #include <list> #include <c

Atcoder Beginner Contest 144 F- Fork the Road(概率DP/期望DP)

Problem Statement There is a cave consisting of NN rooms and MM one-directional passages. The rooms are numbered 11 through NN . Takahashi is now in Room 11 , and Room NN has the exit. The ii -th passage connects Room sisi and Room titi (sisi < titi

HDU4336 Card Collector 概率DP求期望+状压

题目大意:要集齐N张卡片,每包干脆面出现每种卡片的概率已知,问你集齐N张卡片所需要的方便面包数的数学期望(N<=20). solution: 由于N<=20,我们可以考虑状压,设dp[S]表示牌的状态为S时的需要的方便面包数的数学期望. 那么,对于每一个状态,考虑枚举每一张牌i(摸到了i),此时: ① 如果S中不含i,dp[S]+=(dp[S|(1<<i-1)]+1)*p[i]. ② 如果S中已经包含i,那么算到下面的情况中去. 但是注意到,上述情况是已经保证了摸到牌,但是其实可以

HDU 4336 Card Collector(状压 + 概率DP 期望)题解

题意:每包干脆面可能开出卡或者什么都没有,一共n种卡,每种卡每包爆率pi,问收齐n种卡的期望 思路:期望求解公式为:$E(x) = \sum_{i=1}^{k}pi * xi + (1 - \sum_{i = 1}^{k}pi) * [1 + E(x)]$,即能转换到x情况的期望+x情况原地踏步的期望. 因为n比较小,我们可以直接状压来表示dp[x]为x状态时集齐的期望.那么显然dp[111111111] = 0.然后我们状态反向求解.最终答案为dp[0]. 然后来看期望的求解:$E(x) =