现在的位置: 首页 > 综合 > 正文

1354 Mobile Computing(暴力、二进制枚举、简直无情)

2018年04月20日 ⁄ 综合 ⁄ 共 1538字 ⁄ 字号 评论关闭

翘了3节课来A这道题,最后还超时了,也是蛮拼的。。

没做出来主要一个方面就是不会一个二进制数子集的枚举

这里上一下代码:

for(int S0 = S; S0; S0 = (S0 - 1) & S){
    
    
}

这里S0就是S的子集了~!

题目的思路就是枚举所有情况,注意记忆化【话说这题学到了不少】

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
//枚举二叉树的形状
const int maxn = 8;
const int maxd = (1 << 8);
int n;
double ww;
int w[maxn];
int sum[maxd];
int vis[maxd];
double ret;
struct Node{
    double l,r;
    Node(double ll,double rr):l(ll),r(rr){};
};
vector<Node>node[maxd];
void debug(int v){
    if(!v){puts(""); return;}
    debug(v / 2);
    printf("%d",v % 2);
}
bool judge(int S){
    for(int i = 0; i < n; i++)
        if(S == (1 << i))
            return true;
    return false;
}
void dfs(int S){      //枚举now的子集
    if(vis[S]) return;
    vis[S] = 1;
    if(judge(S)){
        node[S].push_back(Node(0,0));
        return;
    }
    //printf("%d\n",S);
    for(int S0 = S; S0; S0 = (S0 - 1) & S)if(S0 != S){
        int l = S0;
        int r = S0 ^ S;
        dfs(l); dfs(r);
        //枚举左右的子集
        for(int i = 0; i < node[l].size(); i++)
            for(int j = 0; j < node[r].size(); j++){
                double l1 = 1.0 * sum[r] / (sum[l] + sum[r]);
                double r1 = 1.0 * sum[l] / (sum[l] + sum[r]);
                double l2 = min(-l1 + node[l][i].l,r1 + node[r][j].l);
                double r2 = max(-l1 + node[l][i].r,r1 + node[r][j].r);
                //printf("[%d]: %.2f %.2f\n",S,l2,r2);
                node[S].push_back(Node(l2,r2));
            }
    }
    return;
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%lf%d",&ww,&n);
        ret = -1;
        memset(vis,0,sizeof(vis));
        for(int i = 0; i < n; i++)
            scanf("%d",&w[i]);
        for(int i = 0; i < (1 << n); i++){
            sum[i] = 0;
            node[i].clear();
            for(int j = 0;j < n; j++){
                if(i & (1 << j)){
                    sum[i] += w[j];
                }
            }
        }
        int S = (1 << n) - 1;
        dfs(S);
        //printf("%d\n",node[S].size());
        for(int i = 0; i < node[S].size(); i++){
            double d = node[S][i].r - node[S][i].l;
            //printf("%.4f %.4f\n",node[S][i].r,node[S][i].l);
            if(d <= ww)
                ret = max(ret,d);
        }
        if(ret < 0) printf("-1\n");
        else
            printf("%.16f\n",ret);
    }
    return 0;
}

抱歉!评论已关闭.