hdu 1342+hdu 2660+hdu 2266+hdu 1704+hdu 1627+hdu 1539

几道搜索水题,搜索要点就是不断剪枝,必要时还要不断恢复路径。

慢慢体会递归的强大!!!

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1342

View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 #define MAXN 55
 6 int num[MAXN];
 7 int path[MAXN];
 8 int k,len;
 9 
10 void dfs(int x,int cnt){
11     path[len++]=num[x];
12     if(cnt==6){
13         printf("%d",path[0]);
14         for(int i=1;i<len;i++)printf(" %d",path[i]);
15         puts("");
16         return ;
17     }
18     for(int i=x+1;i<=k;i++){
19         dfs(i,cnt+1);
20         len--;
21     }
22 }
23 
24 int main(){
25     int t=0;
26     while(~scanf("%d",&k)&&k){
27         if(t++)puts("");
28         for(int i=1;i<=k;i++)scanf("%d",&num[i]);
29         for(int i=1;i<=k;i++){
30             len=0;
31             dfs(i,1);
32         }
33     }
34     return 0;
35 }

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2660

这道题也可以用背包解。

View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 #define MAXN 22
 6 struct Node{
 7     int v,w;
 8 }node[MAXN];
 9 
10 int W,n,k,ans;
11 
12 void dfs(int i,int value,int weight,int count){
13     if(count==k){
14         ans=max(ans,value);
15         return ;
16     }
17     for(int j=i+1;j<=n;j++){
18         if(weight+node[j].w<=W)dfs(j,value+node[j].v,weight+node[j].w,count+1);
19     }
20 }
21 
22 int main(){
23     int _case;
24     scanf("%d",&_case);
25     while(_case--){
26         scanf("%d%d",&n,&k);
27         for(int i=1;i<=n;i++){
28             scanf("%d%d",&node[i].v,&node[i].w);
29         }
30         scanf("%d",&W);
31         ans=0;
32         for(int i=1;i<=n;i++){
33             if(node[i].w<=W)dfs(i,node[i].v,node[i].w,1);
34         }
35         printf("%d\n",ans);
36     }
37     return 0;
38 }

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2266

View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<cmath>
 6 using namespace std;
 7 typedef long long ll;
 8 
 9 #define MAXN 14
10 ll sum,cnt;
11 int len;
12 char str[MAXN];
13 
14 //递归的强大!!!
15 void dfs(int pos,ll s){
16     if(pos==len&&s==sum){
17         cnt++;
18         return ;
19     }
20     ll tmp=0;
21     for(int i=pos;i<len;i++){
22         tmp=tmp*(ll)10+str[i]-'0';
23         dfs(i+1,s+tmp);
24         if(pos!=0)dfs(i+1,s-tmp);//不知为什么,pos改成i就错了。
25     }
26 }
27 
28 int main(){
29     while(~scanf("%s",str)){
30         scanf("%I64d",&sum);
31         cnt=0,len=strlen(str);
32         dfs(0,0);
33         printf("%d\n",cnt);
34     }
35     return 0;
36 }

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1704

这道题也可以用传递闭包来做。

View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 using namespace std;
 6 #define MAXN 555
 7 vector<int>vt[MAXN];
 8 int n,m;
 9 
10 bool dfs(int x,int y){
11     for(int i=0;i<vt[x].size();i++){
12         int u=vt[x][i];
13         if(u==y)return true;
14         if(dfs(u,y))return true;
15     }
16     return false;
17 }
18 
19 int main(){
20     int _case,u,v;
21     scanf("%d",&_case);
22     while(_case--){
23         scanf("%d%d",&n,&m);
24         for(int i=1;i<=n;i++)vt[i].clear();
25         for(int i=1;i<=m;i++){
26             scanf("%d%d",&u,&v);
27             vt[u].push_back(v);
28         }
29         int cnt=0;
30         for(int i=1;i<=n;i++){
31             for(int j=i+1;j<=n;j++){
32                 if(!(dfs(i,j)||dfs(j,i)))cnt++;
33             }
34         }
35         printf("%d\n",cnt);
36     }
37     return 0;
38 }

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1627

View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 #define MAXN 111
 6 int path[MAXN];
 7 int n,l,cnt;
 8 
 9 bool dfs(int cur){
10     if(n==cnt){
11         int k=0,num=0;
12         for(int i=0;i<cur;i++){
13             if(k==4&&num!=16){printf(" ");k=0;}
14             if(num==16){puts("");num=0,k=0;}
15             printf("%c",path[i]+'A');
16             k++;
17             if(k==4)num++;
18         }
19         puts("");
20         printf("%d\n",cur);
21         return true;
22     }
23     for(int i=0;i<l;i++){
24         path[cur]=i;
25         bool flag=false;
26         for(int j=1;j<=(cur+1)/2;j++){
27             flag=true;
28             for(int k=0;k<j;k++){
29                 if(path[cur-k]!=path[cur-j-k]){flag=false;break;}
30             }
31             if(flag)break;
32         }
33         if(flag)continue;
34         cnt++;
35         if(dfs(cur+1))return true;
36     }
37     return false;
38 }
39 
40 
41 int main(){
42     while(~scanf("%d%d",&n,&l)){
43         if(n==0&&l==0)break;
44         memset(path,-1,sizeof(path));
45         cnt=0;
46         dfs(0);
47     }
48     return 0;
49 }

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1539

对这道题略无语,测试数据都说了不超过6位,我开了11位,wa无数次,最后搞了个22位的过了。。。

View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 #define MAXN 22//不是说测试数据不超过6位吗!!!一开始搞了个11的还过不了!!!!
 6 char str[MAXN];
 7 int n,len,relen,ans,l,tag;
 8 int path[MAXN];
 9 int repath[MAXN];
10 
11 //递归+路径保存!!!
12 void dfs(int pos,int sum){
13     if(sum>n)return ;
14     if(pos==len){
15         if(sum<=n&&sum>=ans){
16             if(sum==ans)tag=2;//有多个最接近的值,就rejected
17             else {
18                 ans=sum,relen=0,tag=1;
19                 for(int i=0;i<l;i++)repath[relen++]=path[i];
20             }
21         }
22         return ;
23     }
24     int tmp=0;
25     for(int i=pos;i<len;i++){
26         tmp=tmp*10+str[i]-'0';
27         path[l++]=tmp;
28         dfs(i+1,sum+tmp);
29         l--;
30     }
31 }
32 
33 
34 
35 int main(){
36     while(~scanf("%d%s",&n,str)){
37         if(n==0&&str[0]=='0')break;
38         len=strlen(str);
39         ans=0,l=0,tag=0;
40         memset(path,0,sizeof(path));
41         memset(repath,0,sizeof(repath));
42         dfs(0,0);
43         if(tag==0)puts("error");//都大于n就是error了。
44         else if(tag==2)puts("rejected");
45         else {
46             printf("%d",ans);
47             for(int i=0;i<relen;i++)printf(" %d",repath[i]);
48             printf("\n");
49         }
50     }
51     return 0;
52 }
原文地址:https://www.cnblogs.com/wally/p/3070562.html