【bf】洛谷 P1850 换教室 暴力

版权声明:随便转载。 https://blog.csdn.net/zhang14369/article/details/80712379

一、题目:

洛谷原题

二、思路:

爆搜。
暴力枚举要换的教室,计算期望值,不断更新答案。
我写了两个DFS函数。第一个用来枚举换的教室,第二个用来算期望值,写的很丑,望见谅。
得分:80分。233

三、补充:

补充一下递归实现指数型枚举的模板。

这等价于每个整数可以选或不选,所有可能的方案总数共有 2 n 种。

vector<int>chosen;
inline void calc(int x){
    if(x==n+1){
        for(register int i=0;i<chosen.size();i++){
            printf("%d",chosen[i]);
        }
        puts("");
        return;
    }
    calc(x+1);
    chosen.push_back(x);
    calc(x+1);
    chosen.pop_back();
}

三、代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>
#include<vector>

#define eps 1e-8

using namespace std;
inline int read(void) {
    int x = 0, f = 1; char ch = getchar();
    while (ch<'0' || ch>'9') {
        if (ch == '-')f = -1;
        ch = getchar();
    }
    while (ch >= '0'&&ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return f * x;
}

const int maxn = 2005, maxv = 305;
const double inf = (double)0x3f3f3f;

int n, m, V, E, c[maxn], d[maxn], dis[maxv][maxv], v[maxn], cnt;
double K[maxn], ans = inf;
bool chosen[maxn];

inline void dfs2(int now,double &qiwang) {
    if (now == cnt + 1) {
        int dist = 0;
        for (register int i = 2; i <= n; i++) {
            if (chosen[i - 1]) {
                if (chosen[i]) {
                    dist += dis[d[i]][d[i - 1]];
                }
                else {
                    dist += dis[c[i]][d[i - 1]];
                }
            }
            else {
                if (chosen[i]) {
                    dist += dis[d[i]][c[i - 1]];
                }
                else {
                    dist += dis[c[i]][c[i - 1]];
                }
            }
        }
        double probability = 1.0;
        for (register int i = 1; i <= cnt; i++) {
            if (chosen[v[i]]) { probability *= K[v[i]]; probability += eps; }
            else { probability *= (1.0 - K[v[i]]); probability += eps; }
        }
        qiwang += (double)dist*probability;
        return;
    }
    dfs2(now + 1, qiwang);
    chosen[v[now]] = true;
    dfs2(now + 1, qiwang);
    chosen[v[now]] = false;
}

inline void dfs(int now) {
    if (now == n + 1 || cnt == m) {
        double temp = 0;
        dfs2(1, temp);
        ans = min(ans, temp);
        return;
    }
    dfs(now + 1);
    v[++cnt] = now;
    dfs(now + 1);
    cnt--;
}

inline void init(void) {
    n = read(); m = read(); V = read(); E = read();
    m = min(n, m);
    for (register int i = 1; i <= n; i++) {
        c[i] = read();
    }
    for (register int i = 1; i <= n; i++) {
        d[i] = read();
    }
    for (register int i = 1; i <= n; i++) {
        scanf("%lf", &K[i]);
    }
    //floyd
    memset(dis, 0x3f, sizeof dis);
    for (register int i = 1; i <= V; i++)dis[i][i] = 0;
    for (register int i = 1; i <= E; i++) {
        int x = read(), y = read(), w = read();
        dis[y][x] = dis[x][y] = min(dis[x][y], w);
    }
    for (register int k = 1; k <= V; k++)
        for (register int i = 1; i <= V; i++)
            for (register int j = 1; j <= V; j++)
                dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);

    return;
}

inline void solve(void) {
    dfs(1);
    printf("%.2lf\n", ans);
}

int main()
{
    init();
    solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhang14369/article/details/80712379