• Uva 140 Bandwidth


      基本思路是暴力枚举,思考一下可以发现,可以跳过一下情况。对于目前最小的minBW,每次枚举一种排列计算bandwidth进行比较,如果大于当前minBW已经可以断定这个排列已经不可能是最好的解了。

      而且对于一个点来说,与它相连的点为N,那么就这个点而言,最好情况就是这些点分布在其两侧,bandwidth为ceil(N / 2)

        举例:A:BCDEFG

        对于排列BCDAEFG可以发现其bandwidth为3

          而对后续的排列BCDEAFG来说,B与A的距离就为4,大于之前的最佳情况3了,已经没有必要继续蒜C和A的情况了。

      我采用了<algorithm>中的next_permutaiton()函数,帮忙枚举每一种排列。关于此函数,可参考Reference

      一点收获:就剪枝而言,考虑如何剪枝的时候,要考虑当前点最好的情况是什么,从而在这角度出发,如果某一点连最好的情况都达不到,那么这里就可以剪枝。 就比如这题的bandwidth,如果一个点在最好的情况都不能大于当前的最大值了,就没有必须继续搜索了,所以可以剪枝

      

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    
    const int MAXN = 26 + 5;
    std::vector<int> permu, ans, link[MAXN];
    
    void Link(string &s) {
        int isLink[MAXN][MAXN] = {false};
        size_t pos = 0;
        while(pos < s.size()) {
            int head = s[pos] - 'A';
            pos += 2; // jump over :
            while(pos < s.size() && s[pos] != ';') {
                isLink[head][s[pos] - 'A'] 
                    = isLink[s[pos] - 'A'][head] = true;
                ++ pos;
            }
            ++ pos; // jump over ';'
        }
        for(int i=0; i<MAXN; ++ i) {
            link[i].clear();
            for(int j = 0; j < MAXN; ++ j) {
                if(isLink[i][j]) {
                    link[i].push_back(j);
                }
            }
        }
    }
    
    int Abs(int s) {
        return s > 0 ? s : -s;
    }
    
    int minBW;
    int GetBW() {
        int pos[MAXN];
        for(size_t i = 0; i < permu.size(); ++ i) {
            pos[permu[i]] = i;
        }
        int maxBW = -1;
        for(size_t i = 0; i < permu.size(); ++ i) {
            int tmp = -1;
            int order = permu[i];
            if( ceil(link[order].size() / 2.0) > minBW ) {
                return 1 << 10;
            }
            for(size_t j = 0; j < link[order].size(); ++ j) {
                int dis = Abs(pos[link[order][j]] - i);
                if(dis > minBW) {
                    return 1 << 10;
                }
                tmp = tmp > dis ? tmp : dis;
            }
            maxBW = maxBW > tmp ? maxBW : tmp;
        }
        return maxBW;
    }
    
    int main() {
        ios::sync_with_stdio(false);
        string s;
        while(cin >> s && s != "#") {
            Link(s);
            permu.clear();
            for(int i=0; i<MAXN; ++ i) {
                if(link[i].size()) {
                    permu.push_back(i);
                }
            }
            minBW = 1 << 10;
            do{
                int value = GetBW();
                if(minBW > value) {
                    minBW = value;
                    ans = permu;
                }
            }while(next_permutation(permu.begin(), permu.end()));
            for(size_t i = 0; i < ans.size(); ++ i) {
                cout << char(ans[i]+'A') << " ";
            }
            cout << "-> " << minBW << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    原 java调整数据顺序是奇数位于偶数的前面(思路与实现)
    队列和栈是什么,列出它们的区别?
    python 虚拟环境创建
    系统架构知识
    Git 管理代码
    继承类构造方法使用
    if __name__=="__main__"
    django 项目创建
    python unittest的使用
    python ddt/paramunittest的使用
  • 原文地址:https://www.cnblogs.com/Emerald/p/4709151.html
Copyright © 2020-2023  润新知