版权声明:随便转载。 https://blog.csdn.net/zhang14369/article/details/80712379
一、题目:
二、思路:
爆搜。
暴力枚举要换的教室,计算期望值,不断更新答案。
我写了两个DFS函数。第一个用来枚举换的教室,第二个用来算期望值,写的很丑,望见谅。
得分:80分。233
三、补充:
补充一下递归实现指数型枚举的模板。
这等价于每个整数可以选或不选,所有可能的方案总数共有 种。
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;
}