SRM 542 DIV1 500 StrangeDictionary2
2016-09-13 16:33
309 查看
Task:
给你若干个字符串,然后给它们进行排序,但排序依照的位数是一个随机生成的排列(就是你可能对两个长度为三的字符串,先将它们的第2位进行比较,再比较第1位,再比较第3位才能得到它们的大小关系),那么求出每个字符串的期望排序后在第一位(最小)的可能性,(n<=16)
Solution:
这是一道状压dp题,我们定义dp[S][i]为当前剩下的集合为S,第i个元素可能是最小的可能性,那我们先预处理出如果选第j位进行比较,有哪些字符串会比i小,或者与i相等.如果下一位选第j位,若S&Smaller[j]!=0,则证明选这个是不行的,我们让cnt++,这里的cnt是指这一步我们可以进行的操作总和.而如果S&Equal[j]!=S,则证明选第j位可能使i变的最小,则cnt++,dp[S][i]+=dp[S&Equal[j]][i].最后dp[S][i]/=cnt即可.
这样,我们就推出了dp的转移顺序与方程,然后就能将题目写出来了.
给你若干个字符串,然后给它们进行排序,但排序依照的位数是一个随机生成的排列(就是你可能对两个长度为三的字符串,先将它们的第2位进行比较,再比较第1位,再比较第3位才能得到它们的大小关系),那么求出每个字符串的期望排序后在第一位(最小)的可能性,(n<=16)
Solution:
这是一道状压dp题,我们定义dp[S][i]为当前剩下的集合为S,第i个元素可能是最小的可能性,那我们先预处理出如果选第j位进行比较,有哪些字符串会比i小,或者与i相等.如果下一位选第j位,若S&Smaller[j]!=0,则证明选这个是不行的,我们让cnt++,这里的cnt是指这一步我们可以进行的操作总和.而如果S&Equal[j]!=S,则证明选第j位可能使i变的最小,则cnt++,dp[S][i]+=dp[S&Equal[j]][i].最后dp[S][i]/=cnt即可.
这样,我们就推出了dp的转移顺序与方程,然后就能将题目写出来了.
int sz,L,Smaller[55],Equal[55]; double dp[1<<18][18]; vector<double>ans; vector<string>Words; double Dp1(int S,int now){ if(dp[S][now]>-0.5)return dp[S][now]; if(S==1<<now)return dp[S][now]=1.0; if((int)(S&(1<<now))==0)return dp[S][now]=0; dp[S][now]=0; int cnt=0; for(int i=0;i<L;i++){ if((int)(S&Smaller[i])>0)cnt++; else if((int)(S&Equal[i])!=S){ cnt++; dp[S][now]+=Dp1((int)(S&Equal[i]),now); } } dp[S][now]/=1.0*cnt; return dp[S][now]; } double Dp(int now){ memset(Equal,0,sizeof(Equal)); memset(Smaller,0,sizeof(Smaller)); for(int i=0;i<sz;i++) for(int j=0;j<L;j++) if(Words[now][j]>Words[i][j])Smaller[j]|=1<<i; else if(Words[now][j]==Words[i][j])Equal[j]|=1<<i; return Dp1((1<<sz)-1,now); } class StrangeDictionary2 { public: vector <double> getProbabilities(vector <string> words) { L=words[0].length(),sz=words.size(); for(int i=0;i<1<<sz;i++) for(int j=0;j<sz;j++) dp[i][j]=-1; ans.clear();Words.clear(); for(int i=0;i<sz;i++)Words.push_back(words[i]); for(int i=0;i<sz;i++)ans.push_back(Dp(i)); return ans; } };
相关文章推荐
- StrangeDictionary(SRM542-div2-3)
- TopCoder SRM 727 Div2 500-point TwoDiagonals
- [SRM554-500]TheBrickTowerMediumDivOne
- SRM500 DIV Ⅰ
- TopCoder SRM 663 Div2 Problem 500 - ABBA (思维)
- SRM 598 DIV1 500 pt
- TopCoder SRM 645 Div2 Problem 500 - ConnectingCars (枚举)
- srm 556 div1 500 LeftRightDigitsGame2(DP)
- Topcoder SRM 660 DIV1 500 Privateparty(数学)
- SRM 559 Div1 500 HatRack
- TopCoder - SRM521 div1 500 RangeSquaredSubsets
- TopCoder SRM 646 Div2 Problem 500 - TheGridDivTwo (BFS + 优先队列)
- TopCoder SRM 650 Div2 Problem 500 - TaroFillingAStringDiv2 (DP)
- srm 152 div1 500(简单概率计算)
- (水题)TC SRM 441 DIV 500 PaperAndPaintEasy
- SRM 562 Div1 500 CheckerFreeness
- SRM 606 div2 500 EllysNumberGuessing
- topcoder srm 500 div1
- SRM 615 DIV1 500
- TopCoder SRM 651 Div2 Problem 500 - FoxAndSouvenirTheNext (DP)