前言:本系列(搜索)博客主要介绍的是用DFS解决一些问题,并不是图论中的DFS
dfs相信大家都有了解,TA是一个图论中的算法。
中心思想就是:只要干不死,就往死里干!
具体来说,就是只要符合要求,就一直往前搜,知道不行了再回头搜另一种。还是看题吧。
八皇后:
一道很经典的题目。思路就是每次枚举一个皇后,然后把这个皇后占领的所有格子标记,再枚举下一个就OK了。
#include
using namespace std;
int row[100],col[100],l[100],r[100];
int ans;
void print(){
if(ans<=2){
for(int k=1;k<=n;k++)
cout<n){
print();
return;
}
else{
for(int i=1;i<=n;i++){
if((!col[i]) && (!l[cnt+i]) && (!r[cnt-i+n])){
row[cnt]=i;
col[i]=1;
l[cnt+i]=1;
r[cnt-i+n]=1;
dfs(cnt+1);
//回溯
col[i]=0;
l[cnt+i]=0;
r[cnt-i+n]=0;
}
}
}
}
int main(){
int n;
cin>>n;
dfs(1);
cout<
注意要回溯。
P2392:
为什么此题的作者不仅没被kkksc03封,还成了管理员?!?!?!?!?!?!?!?!?!?!?!?!?!
切入正题,那么由于kkksc03左右脑同时做2题(真牛),我们用一个l记录左脑,r记录右脑,枚举每道题交给哪边的脑子解决,找到两边时间较大值的最小值就结束了。
同时,虽然这题一打眼是贪心,但你会发现交上去全WA(或者几乎全WA)......
所以,老老实实DP或者DFS吧。
#include
using namespace std;
int l,r,ans,tmp;
int s[4];
int t[21][4];
void dfs(int x,int sub){
if(x>s[sub]){
tmp=min(tmp,max(l,r));
return;
}
l+=t[x][sub];
dfs(x+1,sub);
l-=t[x][sub];
r+=t[x][sub];
dfs(x+1,sub);
r-=t[x][sub];
}
int main(){
for(int i=0;i<4;i++)
cin>>s[i];
for(int i=0;i<4;i++){
l=r=0;
tmp=INT_MAX;
for(int j=0;j>t[j][i];
dfs(0,i);
ans+=tmp;
}
cout<
P2036:
思路很简单,dfs每次往后跑,如果超过n了就更新答案,要么添加,要么不添加,分别搜一下,就行了。而且,此题不需要回溯。
#include
using namespace std;
int s[15],b[15];
int n,ans=INT_MAX;
void dfs(int idx,int sour,int bitter){
if(idx>n){
if(sour==1 && bitter==0)
return;
ans=min(abs(sour-bitter),ans);
return;
}
dfs(idx+1,sour*s[idx],bitter+b[idx]);
dfs(idx+1,sour,bitter);
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>s[i]>>b[i];
dfs(1,1,0);
cout<
咦,为什么只有70?呵,满分就是70(我也不知道为什么)。
P1036:
突然发现了这个:数据范围说1小于等于n,所以当n=1,,k
首先肯定要有一个判断素数的函数:
bool isprime(int n){
for(int i=2;i<=n/i;i++){
if(n%i==0)
return false;
}
return true;
}
然后就是剩下的数挨个枚举选不选就行了。
void dfs(int idx,int sum,int lst){
if(idx==k && isprime(sum)){
ans++;
return;
}
for(int i=lst;i
所以下面是完整代码:
#include
using namespace std;
int x[10];
int n,k,ans;
bool isprime(int n){
for(int i=2;i<=n/i;i++){
if(n%i==0)
return false;
}
return true;
}
void dfs(int cnt,int sum,int lst){
if(cnt==k && isprime(sum)){
ans++;
return;
}
for(int i=lst;i>n>>k;
for(int i=0;i>x[i];
dfs(0,0,0);
cout<
OK,以上就是本期的全部内容了。下期我会聊一聊记忆化和剪枝。ヾ( ̄▽ ̄)Bye~Bye~
温馨提示:本期的全部代码直接提交就无法AC,请不要无脑Ctrl C+Ctrl V