标签:
基本思路是暴力枚举,思考一下可以发现,可以跳过一下情况。对于目前最小的minBW,每次枚举一种排列计算bandwidth进行比较,如果大于当前minBW已经可以断定这个排列已经不可能是最好的解了。
而且对于一个点来说,与它相连的点为N,那么就这个点而言,最好情况就是这些点分布在其两侧,bandwidth为ceil(N / 2)
举例:A:BCDEFG
对于排列BCDAEFG可以发现其bandwidth为3
而对后续的排列BCDEAFG来说,B与A的距离就为4,大于之前的最佳情况3了,已经没有必要继续蒜C和A的情况了。
我采用了<algorithm>中的next_permutaiton()函数,帮忙枚举每一种排列。关于此函数,可参考Reference
#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; }
标签:
原文地址:http://www.cnblogs.com/Emerald/p/4709151.html