Problem B. Fairies and Witches
题目传送门:
https://code.google.com/codejam/contest/4384486/dashboard#s=p1
题目意思理解起来有点麻烦,简单说就是要选n条边(n>=3),边与边之间不能有共同端点,并且要能组成一个面积不为0的多边形(即最长边的值小于其他所有边的和),求一共有多少种不同的选择方案。
用了简单的搜索,没想到大数据也竟然很快能过,感觉时间复杂度较难估计。
参考代码:
void dfs(int cur,int n,int& ans,int sum,vector<pair<int,int>>& pq,vector<bool>& canUse,vector<int>& res){
if (res.size()>=3 && sum>res[0]*2)
ans++;
for (int i=cur;i<pq.size();i++) {
int a = pq[i].second / n;
int b = pq[i].second % n;
int len = pq[i].first;
if (canUse[a] && canUse[b]) {
canUse[a] = false;
canUse[b] = false;
res.push_back(len);
dfs(i + 1, n, ans, sum + len, pq, canUse, res);
res.pop_back();
canUse[a] = true;
canUse[b] = true;
}
}
}
int main() {
int no;
cin>>no;
for (int tt=1;tt<=no;tt++){
int n;
cin>>n;
vector<pair<int,int>> pq;
vector<vector<int>> g(n,vector<int>(n));
for (int i=0;i<n;i++)
for (int j=0;j<n;j++) {
cin >> g[i][j];
if (i<=j && g[i][j] > 0)
pq.push_back(make_pair(g[i][j], i * n + j));
}
sort(pq.begin(),pq.end(),greater<pair<int,int>>());
int ans=0;
vector<bool> canUse(n,true);
vector<int> res;
dfs(0,n,ans,0,pq,canUse,res);
cout<<"Case #"<<tt<<": "<<ans<<endl;
}
return 0;
}