题目
Description
给出一个数字N,N<=11.代表有N个人分担N个危险的工作。
每个人对应每个工作,有个危险值
每个人担任其中一项,问每个人危险值相加,最小值是多少。
Input
第一行给出数字N,接下来N行N列
第i行第j列,代表第i个人担负第j个工作的危险值是多少
Output
如题
Sample Input
3
10 2 3
2 3 4
3 4 5
Sample Output
9
HINT
这是一道简单的DFS,直接for循环暴力枚举每一种可能,再定义一个ans变量,每一种方案算完后将他的危险值和ans比较,最后输出即可。
TLE代码:
#include <bits/stdc++.h>
using namespace std;
int maze[12][12];
int n;
int ans=1e9;
bool vis[12];
void dfs(int s,int sum){
//sum为当前危险值,s为当前方案有多少人
if(s==n){
ans=min(ans,sum);
}else{
for (int i=0;i<n;i++){
if(!vis[i]){
vis[i]=1;
dfs(s+1,sum+maze[i][s]);//
vis[i]=0;
}
}
}
}
int main(){
cin>>n;
for (int i=0;i<n;i++){
for (int j=0;j<n;j++){
cin>>maze[i][j];
}
}
dfs(0,0);
cout<<ans;
return 0;
}
这时,一份看起来完美无缺的代码居然TLE了,只能使用搜索的自带技能:剪枝。
优化版:
#include <bits/stdc++.h>
using namespace std;
int maze[12][12];
int n;
int ans=1e9;
bool vis[12];
void dfs(int s,int sum){
if (sum>ans){
return;
}//其实只优化了这里
if(s==n){
ans=min(ans,sum);
}else{
for (int i=0;i<n;i++){
if(!vis[i]){
vis[i]=1;
dfs(s+1,sum+maze[i][s]);
vis[i]=0;
}
}
}
}
int main(){
cin>>n;
for (int i=0;i<n;i++){
for (int j=0;j<n;j++){
cin>>maze[i][j];
}
}
dfs(0,0);
cout<<ans;
return 0;
}