クリークなんて、どうせバックトラック。3 m >= 2 n の条件から、16個くらいの頂点を消すことを考える。
const int N = 50 + 1;
vector< pair<int, int> > e;
bool del[N];
vector<int> mp;
int rec(int depth, int size, int begin)
{
int rem = size - depth;
unless (rem * 3 >= size * 2) return -1;
int mx = -(1 << 28);
for (int i = begin; i < e.size(); ++i) {
int a = e[i].first;
int b = e[i].second;
if (!del[a] && !del[b]) {
del[a] = true;
mx = max(mx, rec(depth + 1, size, i + 1));
del[a] = false;
del[b] = true;
mx = max(mx, rec(depth + 1, size, i + 1));
del[b] = false;
break;
}
}
if (mx < -1) {
mx = 0;
for (int i = 0; i < size; ++i) {
unless (del[i]) mx += mp[i];
}
}
return mx;
}
class MagicMolecule {
public:
int maxMagicPower(vector <int> mp_, vector <string> g)
{
mp = mp_;
e.clear();
const int n = g.size();
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if (g[i][j] == 'N') e.push_back(make_pair(i, j));
}
}
fill(del, del + N, false);
return rec(0, n, 0);
}
};