UVALive 6514:Crusher’s Code(概率dp)

题目链接 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-1) ;
    int j = i + 1 ;
    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[50000];

int getid(int a) {
    if (id[a] == 0) id[a] = idp++;
    return id[a];
}

int hash(int a[], int n) {
    int ret = 0;
    for (int i = 0; i < n; i++) {
        ret = ret*10 + 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 0;
    if (e[getid(a)] != 0) return e[getid(a)];
    
    int tmp[10];
    int tmpa = a;
    for (int i = n-1; i >= 0; i-- ) {
        tmp[i] = tmpa%10;
        tmpa/=10;
    }

    int num = 0;
    for (int i = 0; i < n; i++) {
        for (int j = i+1; j < n; j++) {
            if (tmp[i] > tmp[j]) num++;
        }
    }

    if (num == 0) {
        isSortedA = a;
        return 0;
    }

    double ans = n*n/(num*2.0);
    for (int i = 0; i < n; i++) {
        for (int j = i+1; 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 0;
    if (e[getid(a)] != 0) return e[getid(a)];
    
    int tmp[10];
    int tmpa = a;
    for (int i = n-1; i >= 0; i-- ) {
        tmp[i] = tmpa%10;
        tmpa/=10;
    }

    int num = 0;
    for (int i = 0; i < n-1; i++) {
        if (tmp[i] > tmp[i+1]) num++;
    }

    if (num == 0) {
        isSortedA = a;
        return 0;
    }

    double ans = (n-1.0)/num;
    for (int i = 0; i < n-1; i++) {
        int j = i+1;
        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[10];

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {

        isSortedA = -1;

        scanf("%d", &n);
        int tmp[10];
        for (int i = 0; i < n; i++) {
            scanf("%d", &a[i]);
            tmp[i] = a[i];
        }
        sort(tmp, tmp+n);
        unique(tmp, tmp+n);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (a[i] == tmp[j]) {
                    a[i] = j;
                    break;
                }
            }
        }

        idp = 0;
        id.clear();
        memset(e,0,sizeof(e));
        printf("Monty %.6lf ", monty(hash(a,n)));

        idp = 0;
        id.clear();
        memset(e,0,sizeof(e));
        printf("Carlos %.6lf
", carlos(hash(a,n)));;

    }
    return 0;
}
原文地址:https://www.cnblogs.com/shinecheng/p/3993700.html