逐渐领悟dfs暴搜的真谛,配上一定的剪枝是真的优雅
爱了鸭1!!!!!!!
解题:
(剪枝)
记录一个最大值,如果当前搜索过程中的最大值 + 剩下层数 * maxv <= res
则不可能更新最大值 , 直接return
故只需要加一句剪枝代码:
if (s + (n - x + 1) * maxv <= res)
结果:
return;
AC code:
#include<iostream>
using namespace std;
const int N=15;
int n,a[N][N],res,mmax;
bool vis[N];
void dfs(int num,int sum) {
//剪枝
if(sum+mmax*(n-num+1)<res) { //在遍历到num层已有sum相似度和,尽管接下来每层都选最大值还是比res(目前整体最大相似度和小)
//就return;
return ;
}
if(num>n) { //结束
res=max(res,sum);
return;
}
for(int j=1; j<=n; j++) { //第num行的所有列
if(vis[j])continue;//该列已经被选
vis[j]=true;
dfs(num+1,sum+a[num][j]);
vis[j]=false;//回溯
}
}
int main() {
cin>>n;
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
cin>>a[i][j];
mmax=max(mmax,a[i][j]);//dfs中剪枝用的
}
}
dfs(1,0);
cout<<res<<"\n";
return 0;
}