SRM 664 Div2 Hard: BearSortsDiv2(归并排序)
来源:互联网 发布:移动数据打开要收费吗 编辑:程序博客网 时间:2024/04/29 23:51
Problem Statement
Bear Limak was chilling in the forest when he suddenly found a computer program. The program was a correct implementation of MergeSort. Below you can find the program in pseudocode.
# mergeSort(left,right) sorts elements left, left+1, ..., right-1 of a global array Tfunction mergeSort(left,right): # if there is at most one element, we are done if left+1 >= right: return # otherwise, split the sequence into halves, sort each half separately mid = (left + right) div 2 mergeSort(left,mid) mergeSort(mid,right) # then merge the two halves together merged = [] # an empty sequence p1 = left p2 = mid while (p1 < mid) or (p2 < right): if p1 == mid: merged.append( T[p2] ) p2 += 1 else if p2 == right: merged.append( T[p1] ) p1 += 1 else: if(pos[a[p1]] < pos[a[p2]]) tmp.push_back(a[p1++]); else tmp.push_back(a[p2++]); # finally, move the merged elements back into the original array for i from left to right-1 inclusive: T[i] = merged[i-left]
Limak noticed that one part of the implementation was missing: the function LESS. You can probably guess that the function is supposed to return a boolean value stating whether the first argument is less than the second argument. However, Limak is a bear and he didn't know that. Instead he implemented his own version of this function. Limak's function uses a true random number generator. Each of the two possible return values (true, false) is returned with probability 50 percent.
The random values generated in different calls to Limak's function LESS are mutually independent. Note that even if you call LESS twice with the same arguments, the two return values may differ.
After implementing LESS, Limak decided to run his brand new program. He initialized the global array T to contain N elements. Then, he filled the values 1 through N into the array: for each valid i, he set T[i] to i+1. Finally, he executed the function mergeSort(0,N).
Even with Limak's new LESS function, the program never crashes. On the other hand, it does not necessarily produce a sorted sequence when it terminates. In general, when the program terminates, the array T will contain some permutation of the numbers 1 through N.
After running the program many times, Limak has noticed that different output permutations are produced with different probabilities. Your task is to help him learn more about these probabilities. More precisely, your task is to compute the probability that a given sequence will appear as the output of Limak's program.
You are given a vector <int> sortedSequence with N elements, containing a permutation of 1 through N. Let P be the probability that Limak's program, when run on an array with N elements, outputs this permutation. Return the value log(P), where log denotes the natural (base e) logarithm.
Definition
Class:BearSortsDiv2Method:getProbabilityParameters:vector <int>Returns:doubleMethod signature:double getProbability(vector <int> seq)(be sure your method is public)Limits
Time limit (s):2.000Memory limit (MB):256Stack limit (MB):256Notes
-Your return value must have absolute or relative error smaller than 1e-9.-You may assume that for each N and for each permutation P of 1 through N the probability that P appears as the output of Limak's program is strictly positive.Constraints
-sortedSequence will contain exactly N elements.-N will be between 1 and 40, inclusive.-Elements of sortedSequence will be between 1 and N, inclusive.-Elements of sortedSequence will be pairwise distinct.题目大意:
归并排序过程中,“归并”这步是:
if( isless(a[p1]],a[p2]) ) tmp.push_back(a[p1++]);
else tmp.push_back(a[p2++]);
isless()函数等概率返回真假。
求最后归并得到某一给定的数列的概率是多少
(输出log(概率))
思路:
归并是决定两个数之间的顺序,已知给定数列,显然只有一种归并方式
所以再模拟一遍归并排序就能算出概率
//#pragma comment(linker, "/STACK:1024000000,1024000000")#include <iostream>#include <cstring>#include <cmath>#include <queue>#include <stack>#include <map>#include <set>#include <string>#include <vector>#include <cstdio>#include <ctime>#include <bitset>#include <algorithm>#define SZ(x) ((int)(x).size())#define ALL(v) (v).begin(), (v).end()#define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i)#define REP(i,n) for ( int i=1; i<=int(n); i++ )using namespace std;typedef long long ll;#define X first#define Y secondtypedef pair<int,int> pii;const int N = 1e3+100;int pos[N];vector<int>tmp;int a[N];double ans = 0;void Merge(int l,int r){ if( l+1 >= r) return ; int m = (l+r)>>1; Merge(l,m),Merge(m,r); int p1 = l, p2 = m; while(p1 < m || p2 < r){ if(p1 == m) tmp.push_back(a[p2++]); else if(p2 == r) tmp.push_back(a[p1++]); else{ ans += log(0.5);//log(a*b) = loga + logb if(pos[a[p1]] < pos[a[p2]]) tmp.push_back(a[p1++]); else tmp.push_back(a[p2++]); } } foreach(it,tmp) a[l++] = *it; tmp.clear();}class BearSortsDiv2 {public: double getProbability( vector <int> seq ) { int top = 0; ans = 0; foreach(it,seq){ a[top] = top+1; pos[*it] = top++; } Merge(0,SZ(seq)); return ans; }};
- SRM 664 Div2 Hard: BearSortsDiv2(归并排序)
- Topcoder SRM 663 Div2 Hard: CheeseRolling(状压DP)
- DP SRM 661 Div2 Hard: ColorfulLineGraphsDiv2
- SRM 719 div2 Hard (01Trie,最大异或和)
- SRM 466 (DIV1 DIV2 )
- 拓扑排序 SRM 660 Div2 Medium: PrivateD2party
- TopCoder SRM 664 Div2 Level One
- TopCoder SRM 664 Div2 Level Three
- 记第一次SRM (SRM489 div2)
- srm 653 div2 1000(dp)
- srm 300 div2 1000(贪心进阶)
- srm 305 div2 1050(bfs中级)
- srm 307 div2 1000(数论,枚举)
- srm 656 div2 1000(dp+组合)
- SRM 678 div2 (1000题待补)
- SRM 664 hard BearSorts题解搬运
- SRM 114 DIV2 [550]
- SRM 398 DIV2 [250]
- 设置应用程序图标
- 求第n个丑数
- ajax实现带进度条的文件上传
- C++14新特性
- zookeeper实现原理
- SRM 664 Div2 Hard: BearSortsDiv2(归并排序)
- collectionView学习
- Java参数传递方式
- 数据发布与订阅
- C语言系列--时间处理
- 一步一步教你做LIS接口教程(一)
- cassandra的四种key
- cocos2d-x学习日记 - 1. 基础概念 - 导演, 场景, 层, 精灵
- Leetcode #222 Count Complete Tree Nodes