zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    【bzoj4596】[Shoi2016]黑暗前的幻想乡 容斥原理+矩阵树定理
    【bzoj4832】[Lydsy1704月赛]抵制克苏恩 期望dp
    【bzoj3796】Mushroom追妹纸 hash/sa+kmp+二分
    【bzoj3309】DZY Loves Math 莫比乌斯反演+线性筛
    【bzoj2813】 奇妙的Fibonacci数列 线性筛
    面向对象实现简单的学生课程选择
    小案例--面向对象中实现分页
    初识面向对象四(装饰器/反射)
    python小技巧--控制台输出带颜色的文字方法
    初识面向对象三(经典类/多态/鸭子类型/初识封装)
  • 原文地址:https://www.cnblogs.com/wally/p/3070562.html
Copyright © 2011-2022 走看看