UVALive 3403 Mobile Computing——爆搜

版权声明:欢迎大家转载,转载请注明出处 https://blog.csdn.net/hao_zong_yin/article/details/83036417

有点像状压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;
}

猜你喜欢

转载自blog.csdn.net/hao_zong_yin/article/details/83036417
今日推荐