zoukankan      html  css  js  c++  java
  • Codeforces Round #325 (Div. 2) F:(meet in the middle)

    一看题就觉得3^25暴力肯定挂。但是并不能想出思路

    就当学习了,代码基本copy菊苣的。

    前半部分暴力搜,将搜到的状态存在map里,这里只保存b-a和c-b是为了匹配方便

    后半部分也是暴力搜状态,找到的状态去map里查询(比如后半搜到5,6,去map里找-5,-6)

    感觉map好慢。看来有时候得去学习一下手写哈希表了

    至于状态的保存,一开始想把每个操作保存为一个三位二进制,发现2^75位好像会爆啊。。

    看了菊苣的才知道可以保存2位就好(3个状态)

    膜拜菊苣。果然我还太渣

    有个坑是全0 的数据。所以把ans初始化为-INF

    #include"cstdio"
    #include"queue"
    #include"cmath"
    #include"stack"
    #include"iostream"
    #include"algorithm"
    #include"cstring"
    #include"map"
    #include"queue"
    #include"vector"
    #define ll long long
    
    using namespace std;
    const int MAXN = 200050;
    const int MAXE = 400050;
    const int INF = 0x3f3f3f3f;
    
    map<pair<int,int>,pair<int,ll> >H;
    pair<int ,ll> ans;
    int n,s[30],l[30],m[30],w[30];
    
    
    void dfs1(int a,int b,int c,int dep,ll s){//前半部分暴力
        if(dep>=(n+1)/2+1){
            pair<int,ll> t=H[pair<int,int>(a-b,b-c)];
            if(t.second==0) H[pair<int,int>(a-b,b-c)]=pair<int,ll>(a,s);
            else H[pair<int,int>(a-b,b-c)]=max(t,pair<int,ll>(a,s));//比较first
            return;
        }
        dfs1(a+l[dep],b+m[dep],c,dep+1,s<<2|1);
        dfs1(a+l[dep],b,c+w[dep],dep+1,s<<2|2);
        dfs1(a,b+m[dep],c+w[dep],dep+1,s<<2|3);
    }
    
    void dfs2(int a,int b,int c,int dep,ll s){
        if(dep>=n+1){
            pair<int,ll> t=H[pair<int,int>(b-a,c-b)];
            if(t.second==0) return ;
            ans=max(ans,pair<int,ll>(a+t.first,t.second<<(n-(n+1)/2<<1)|s));
            return;
        }
        dfs2(a+l[dep],b+m[dep],c,dep+1,s<<2|1);
        dfs2(a+l[dep],b,c+w[dep],dep+1,s<<2|2);
        dfs2(a,b+m[dep],c+w[dep],dep+1,s<<2|3);
    }
    
    
    int main(){
        ans.first=-INF;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d%d%d",&l[i],&m[i],&w[i]);
        dfs1(0,0,0,1,0);
        dfs2(0,0,0,(n+1)/2+1,0);
        if(ans.first==-INF) printf("Impossible
    ");
        else{
            for(int i=0;i<n;i++){
                s[i]=ans.second&3;
                ans.second>>=2;
            }
            for(int i=n-1;i>=0;i--){
                if(s[i]==1) printf("LM
    ");
                else if(s[i]==2) printf("LW
    ");
                else printf("MW
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    hdu 1042 N!
    hdu 1002 A + B Problem II
    c++大数模板
    hdu 1004 Let the Balloon Rise
    hdu 4027 Can you answer these queries?
    poj 2823 Sliding Window
    hdu 3074 Multiply game
    hdu 1394 Minimum Inversion Number
    hdu 5199 Gunner
    九度oj 1521 二叉树的镜像
  • 原文地址:https://www.cnblogs.com/luxiaoming/p/5068095.html
Copyright © 2011-2022 走看看