天天写算法之Sequence one

这个题,我发现了不是所有的dfs都必须要用到vis[i]= 1   ~dfs~ vis[i]=0,这样的结构。
这个题技巧好多,膜拜了一波大神代码,按着思路摸了一遍。

主要是注意整体的解题思路以及减枝操作:
技巧一:重判,这里有两个重判, 第一个重判是判断如果搜索的是子序列的第一个元素,那么判断从原始序列开始到当前位置是否已经出现过该元素,若出现过则之前肯定搜索过该元素,则放弃该元素的搜索。第二个重判,当搜索的不是子序列的第一个元素时,则判断子序列的前一个元素对应原始序列的位置,然后从该位置下一个元素开始到到当前搜索的位置之前判断该元素是否出现过,如果出现过,说明该子串出现过重复的,则放弃该元素。这里的两个重判需要好好地想想,很巧妙。
技巧二:剪枝,这里的一个剪枝技巧是做了一个标记位,假如我在搜索长度为3的子串时,发现没有一个符合的,那么就不可能存在长度为4的子串符合条件。如果没有这个剪枝就会超时,看来影响很大的

代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 1010
  struct Node{
      int num,pos;
  }path[MAXN];

 int num[MAXN];
 int n,p,_count,len;
 bool flag;

 bool Judge(int st,int ed){
     for(int i=st;i<ed;i++){
         if(num[i]==num[ed])return false;
     }
     return true;
 }

 void dfs(int l,int pos){
     if(_count>=p)return ;
     if(l==len){
         _count++;
         flag=true;
         for(int i=0;i<l-1;i++){
            cout << path[i].num<<" ";
         }
         cout << path[l-1].num<<endl;
         return ;
     }
     for(int i=pos;i<n;i++){
         if((l!=0&&path[l-1].num<=num[i])||l==0){
             if(l!=0&&!Judge(path[l-1].pos+1,i))continue;
             if(l==0&&!Judge(0,i))continue;
             path[l].num=num[i];
             path[l].pos=i;
             dfs(l+1,i+1);
         }
     }
 }


 int main(){
     while(cin>>n>>p){
         for(int i=0;i<n;i++)
             cin>>num[i];
         _count=0;
         for(int i=1;i<n;i++){
             flag=false;
             len=i;
             dfs(0,0);
             if(_count>=p||(!flag))break;
         }
         cout <<endl;
     }
     return 0;
 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值