UVALive 3403 Mobile Computing——爆搜
阿新 • • 發佈:2018-11-16
有點像狀壓dp的爆搜
#include <bits/stdc++.h> using namespace std; typedef pair<double, double> P; const int maxn = 10; const double eps = 1e-6; int dcmp(double x) { if (fabs(x) < eps) return 0; return x < 0 ? -1 : 1; } int T; double r; int s, w[maxn], sum[1<<maxn]; vector<P> vec[1<<maxn]; void dfs(int s) { if (vec[s].size() != 0) return; bool isleaf = true; for (int s0 = (s-1)&s; s0; s0 = (s0-1)&s) { int s1 = (s ^ s0); dfs(s0); dfs(s1); double a = 1.0*sum[s1]/(sum[s0]+sum[s1]); double b = 1.0 - a; for (int i = 0; i < vec[s0].size(); i++) { for (int j = 0; j < vec[s1].size(); j++) { double aa = max(a+vec[s0][i].first, vec[s1][j].first-b); double bb = max(b+vec[s1][j].second, vec[s0][i].second-a); if (dcmp(aa+bb-r) <= 0) vec[s].push_back(make_pair(aa, bb)); } } isleaf = false; } if (isleaf) vec[s].push_back(make_pair(0, 0)); } int main() { scanf("%d", &T); while (T--) { scanf("%lf%d", &r, &s); for (int i = 0; i < s; i++) scanf("%d", &w[i]); for (int i = 0; i < (1<<s); i++) { vec[i].clear(); sum[i] = 0; for (int j = 0; j < s; j++) { if (i&(1<<j)) sum[i] += w[j]; } } int all = (1<<s)-1; dfs(all); double ans = -1; for (int i = 0; i < vec[all].size(); i++) { ans = max(ans, vec[all][i].first+vec[all][i].second); } if (dcmp(ans) < 0) printf("-1\n"); else printf("%.16lf\n", ans); } return 0; }