HDU 4418 (期望dp 高斯消元)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/du_lun/article/details/82049027
#include<bits/stdc++.h>
using namespace std;
const int N=200;
double p[N], eps=1e-10,  sp;
int n, m, Y, X, D;
bool vis[N];

/****************************///高斯消元模板
int equ, var, a[N][N], x[N];
int Gauss(){
    int i, j, k, col, max_r;
    for(int k=0, col=0; k<equ&&col<var; k++, col++){
        max_r=k;
        for(i=k+1; i<equ; i++)
            if(fabs(a[i][col])>fabs(a[max_r][col]))
                max_r=i;
        if(fabs(a[max_r][col])<eps) return 0;
        if(k!=max_r){
            for(j=col; j<n; j++)
                swap(a[k][j], a[max_r][j]);
            swap(x[k], x[max_r]);
        }
        x[k]/=a[k][col];
        for(j=col+1; j<var; j++) a[k][j]/=a[k][col];
        a[k][col]=1;
        for(i=0; i<equ; i++)
        if(i!=k){
            x[i]-=x[k]*a[i][col];
            for(j=col+1; j<var; j++) a[i][j]-=a[k][j]*a[i][col];
            a[i][col]=0;
        }
    }
    return 1;
}
/******************************************/

void gouzao(){
    memset(a, 0, sizeof a);
    memset(x, 0, sizeof x);
    for(int i=0; i<n; i++){
        a[i][i]=1;
        if(!vis[i]) continue;
        if(i==Y || i==(n-Y)%n){
            x[i]=0; continue;
        }

        for(int j=1; j<=m; j++){
            a[i][(i+j)%n]-=p[j];
            x[i]+=j*p[j];
        }
    }
}
/**************************************************/
bool BFS(){
    queue<int> q;
    q.push(X);
    vis[X]=1;
    while(!q.empty()){
        int it=q.front(); q.pop();
        for(int i=1; i<=m; i++){
            if(p[i]<eps) continue;
            int to=(it+i)%n;
            if(!vis[to]){
                vis[to]=true; q.push(to);
            }
        }
    }
    if(vis[Y]||vis[n-Y])
        return true;
    else
        return false;
}

int main(){
    int T;

    scanf("%d", &T);
    while(T--){
        sp=0;
        memset(vis, false, sizeof vis);
        scanf("%d%d%d%d%d", &n, &m, &Y, &X, &D);
        int tmp;
        for(int i=1; i<=m; i++){
            scanf("%d", &tmp);
            p[i]=1.*tmp/100;
            sp+=i*p[i];
        }

        if(Y==X){
            printf("0.00\n");
            continue;
        }
        n=(n-1)<<1;
        if(D==1) X=n-X;
        equ=var=n;
        if(!BFS()){
            printf("Impossible !\n");
            continue;
        }

        gouzao();
        if(Gauss())
            printf("%.2f\n", x[X]);
        else
            printf("Impossible !\n");

    }
    return 0;
}
模板二:
double a[N][N], x[N];
bool free_x[N];
int sgn(double x){
    return (x>eps)-(x-eps);
}
int gauss(){
    int i, j, k, max_r, col;
    double tmp;
    int free_x_num, free_index;
    int equ=n, var=n;
    col=0;
    memset(free_x, true, sizeof free_x);
    for(k=0; k<equ && col<var; k++, col++){
        max_r=k;
        for(i=k+1; i<equ; i++){
            if(sgn(fabs(a[i][col])-fabs(a[max_r][col]))>0) max_r=i;
        }
        if(max_r!=k){
            for(j=k; j<var+1; j++) swap(a[k][j], a[max_r][j]);
        }
        if(sgn[a[k][col])==0){
            k--; continue;
        }
        for(i=k+1; i<equ; i++){
            if(sgn(a[i][col])!=0){
                double t=a[i][col]/a[k][col];
                for(j=col; j<var+1; j++){
                    a[i][j]=a[i][j]-a[i][j]*t;
                }
            }
        }
    }
    for(i=k; i<equ; i++){
        if(sgn(a[i][col])!=0) return 0;
    }
    if(k<var){
        for(i=k-1; i>=0; i--){
            free_x_num=0;
            for(j=0; j<var; j++){
                if(sgn[a[i][j]]!=0 && free_x[j]){
                    free_x_num++, free_index=j;
                }
            }
            if(free_x_num>1) continue;
            tmp=a[i][var];
            for(j=0; j<var; j++){
                if(sgn[a[i][j]]!=0 && j!=free_index) tmp-=a[i][j]*x[j];
            }
            x[free_index]=tmp/a[i][free_index];
            free_x[free_index]=0;
        }
        return var-k;
    }
    for(i=var-1; i>=0; i--){
        tmp=a[i][var];
        for(j=i+1; j<var; j++){
            if(sgn(a[i][j])!=0) tmp-=a[i][j]*x[j];
        }
        x[i]=tmp/a[i][i];
    }
    return 1;
}

猜你喜欢

转载自blog.csdn.net/du_lun/article/details/82049027