Sequence one

//去重,结合原序列。

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

earch is important in the acm algorithm. When you want to solve a problem by using the search method, try to cut is very important.
Now give you a number sequence, include n (<=1000) integers, each integer not bigger than 2^31, you want to find the first P subsequences that is not decrease (if total subsequence W is smaller than P, than just give the first W subsequences). The order of subsequences is that: first order the length of the subsequence. Second order the sequence of each integer’s position in the initial sequence. For example initial sequence 1 3 2 the total legal subsequences is 5. According to order is {1}; {3}; {2}; {1,3}; {1,2}. {1,3} is first than {1,2} because the sequence of each integer’s position in the initial sequence are {1,2} and {1,3}. {1,2} is smaller than {1,3}. If you also can not understand , please see the sample carefully. 
 
Input
The input contains multiple test cases.
Each test case include, first two integers n, P. (1<n<=1000, 1<p<=10000). 
 
Output
For each test case output the sequences according to the problem description. And at the end of each case follow a empty line.
 


#include<iostream>
using namespace std;
typedef struct node{
  int i;
  int pos;


}Node;
Node nodes[1001];
int numbers[1001];


int N,P;
bool equal(int i,int k)
{
   for(int j=i;j<k;j++)
   {
      if(numbers[j]==numbers[k])
 {
   return true;
 }
   }
   return false;


}
int count=0;
bool isover=false;
bool isfind=false;
void dfs(int k,int len,int t)
{
if(count>=P)
{
 return;
}
   if(k>=len)
   {
  isfind=true;
       count++;
 
      for(int m=0;m<len-1;m++)
 {
    cout<<nodes[m].i<<" ";
 
 }
 cout<<nodes[len-1].i<<endl;
      return;
   }
   for(int j=t;j<N;j++)
   { 
  if((k!=0&&numbers[j]>=nodes[k-1].i)||k==0)
  {  
   if(k==0&&equal(0,j))
 {


  continue;
}
 
  
 
 
 if(k>0&&equal(nodes[k-1].pos+1,j))
 {
 continue;
 }
 
 
      nodes[k].i=numbers[j];
  nodes[k].pos=j;

       dfs(k+1,len,j+1);


 
 
  }
 
 }
 return;


}
int main()
{


// freopen("in.txt","r",stdin);


while(cin>>N>>P)
{
  for(int i=0;i<N;i++)
  {
     cin>>numbers[i];
 
  }
 
  
 
  count=0;
  for(int j=1;j<=N;j++)
  {
     isfind=false;
 
  dfs(0,j,0);
 if(!isfind||count>=P)
 {
   break;
 }
  
  }
  cout<<endl;

}
  return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值