【bf】洛谷 P1850 換教室 暴力
阿新 • • 發佈:2019-02-01
一、題目:
二、思路:
爆搜。
暴力列舉要換的教室,計算期望值,不斷更新答案。
我寫了兩個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;
}