题目链接 https://icpcarchive.ecs.baylor.edu/external/65/6514.pdf
题意:给出n个数(n<8) 求这n个数分别两个程序排成有序时,程序的期望迭代次数。排序程序如下。
// Monty's Code
while (!sorted(a)) {
int i = random(n) ;
int j = random(n) ;
if (a[min(i,j)] > a[max(i,j)])
swap(a[i], a[j]) ;
} //Carlos's Code
while (!sorted(a)) {
int i = random(n-) ;
int j = i + ;
if (a[i] > a[j])
swap(a[i], a[j]) ;
}
思路:正常的概率dp。这里“亮”的地方在与,其状态的定义就暴力的定义成了这个串。……因为 8! < 50000。 所以能过。
代码[略锉]:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std; map<int,int> id;
int idp;
int isSortedA;
double e[]; int getid(int a) {
if (id[a] == ) id[a] = idp++;
return id[a];
} int hash(int a[], int n) {
int ret = ;
for (int i = ; i < n; i++) {
ret = ret* + a[i];
}
return ret;
} int n; //monty(anow) = p1*monty(anext1) + p2*monty(anext2) + .. + (1-p1-p2)*monty(anow) + 1;
//p = 2/n*n
double monty(int a) {
if (a == isSortedA) return ;
if (e[getid(a)] != ) return e[getid(a)]; int tmp[];
int tmpa = a;
for (int i = n-; i >= ; i-- ) {
tmp[i] = tmpa%;
tmpa/=;
} int num = ;
for (int i = ; i < n; i++) {
for (int j = i+; j < n; j++) {
if (tmp[i] > tmp[j]) num++;
}
} if (num == ) {
isSortedA = a;
return ;
} double ans = n*n/(num*2.0);
for (int i = ; i < n; i++) {
for (int j = i+; j < n; j++) {
if (tmp[i] > tmp[j]) {
swap(tmp[i], tmp[j]);
ans += 1.0/num * monty(hash(tmp,n));;
swap(tmp[i], tmp[j]);
}
}
}
return e[getid(a)] = ans;
} double carlos(int a) {
if (a == isSortedA) return ;
if (e[getid(a)] != ) return e[getid(a)]; int tmp[];
int tmpa = a;
for (int i = n-; i >= ; i-- ) {
tmp[i] = tmpa%;
tmpa/=;
} int num = ;
for (int i = ; i < n-; i++) {
if (tmp[i] > tmp[i+]) num++;
} if (num == ) {
isSortedA = a;
return ;
} double ans = (n-1.0)/num;
for (int i = ; i < n-; i++) {
int j = i+;
if (tmp[i] > tmp[j]) {
swap(tmp[i], tmp[j]);
ans += 1.0/num * carlos(hash(tmp,n));;
swap(tmp[i], tmp[j]);
}
}
return e[getid(a)] = ans;
} int a[]; int main() {
int t;
scanf("%d", &t);
while (t--) { isSortedA = -; scanf("%d", &n);
int tmp[];
for (int i = ; i < n; i++) {
scanf("%d", &a[i]);
tmp[i] = a[i];
}
sort(tmp, tmp+n);
unique(tmp, tmp+n);
for (int i = ; i < n; i++) {
for (int j = ; j < n; j++) {
if (a[i] == tmp[j]) {
a[i] = j;
break;
}
}
} idp = ;
id.clear();
memset(e,,sizeof(e));
printf("Monty %.6lf ", monty(hash(a,n))); idp = ;
id.clear();
memset(e,,sizeof(e));
printf("Carlos %.6lf\n", carlos(hash(a,n)));; }
return ;
}