标签:
基本思路是暴力枚举,思考一下可以发现,可以跳过一下情况。对于目前最小的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