Sequence one
Problem Description
Search 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.
Sample Input
3 5
1 3 2
3 6
1 3 2
4 100
1 2 3 2
Sample Output
1
3
2
1 3
1 2
1
3
2
1 3
1 2
1
2
3
1 2
1 3
2 3
2 2
1 2 3
1 2 2
题意:给出一个序列,要你输出这个序列的前p个序列(若总排列w<p,则只需要输出w个)
排列方式:
0.序列为原序列的非减子序列
1.length从小到大
2.length相同的话,位置前的排在前面
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
技巧一:重判,这里有两个重判,第一个重判是判断如果搜索的是子序列的第一个元素,那么判断从原始序列开始到当前位置是否已经出现过该元素,若出现过则之前肯定搜索过该元素,则放弃该元素的搜索。第二个重判,当搜索的不是子序列的第一个元素时,则判断子序列的前一个元素对应原始序列的位置,然后从该位置下一个元素开始到到当前搜索的位置之前判断该元素是否出现过,如果出现过,说明该子串出现过重复的,则放弃该元素。
技巧二:剪枝,这里的一个剪枝技巧是做了一个标记位flag,假如我在搜索长度为3的子串时,发现没有一个符合的,那么就不可能存在长度为4的子串符合条件。如果没有这个剪枝就会超时。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
这道题有一个地方使我wa了很久,写在了注释里面。
1 #include<iostream> 2 #include<set> 3 #include<cstring> 4 #define LL long long 5 using namespace std; 6 7 const int maxn=1010; 8 LL a[maxn]; 9 LL ans[10000]; 10 int n,p,len; 11 bool flag; 12 13 set<LL>ssss; 14 set<LL>::iterator it; 15 16 void dfs(int cur,int cnt) 17 { 18 if(cnt>len) 19 return ; 20 ans[cnt]=a[cur]; 21 if(cnt==len) 22 { 23 for(int i=1;i<cnt;i++) 24 cout<<ans[i]<<" "; 25 cout<<ans[cnt]<<endl; 26 flag=true; 27 p--; 28 return ; 29 } 30 //开始这个set是写在了函数外面,然后一直wa 31 //写在外面,dfs操作的其实一直是同一个s,前面的可能也会被clear() 32 set<LL>s; 33 s.clear(); 34 for(int i=cur+1;i<=n;i++) 35 { 36 if(a[i]>=a[cur]&&p>0) 37 { 38 it=s.find(a[i]); 39 if(it!=s.end()) 40 continue; 41 dfs(i,cnt+1); 42 s.insert(a[i]); 43 } 44 } 45 } 46 47 int main() 48 { 49 while(cin>>n>>p) 50 { 51 for(int i=1;i<=n;i++) 52 cin>>a[i]; 53 int m=0; 54 ssss.clear(); 55 for(int i=1;i<=n;i++) 56 { 57 it=ssss.find(a[i]); 58 if(it!=ssss.end()) 59 continue; 60 cout<<a[i]<<endl; 61 ssss.insert(a[i]); 62 m++; 63 if(m>=p) 64 break; 65 } 66 p-=m; 67 len=2; 68 ssss.clear(); 69 while(p>0&&len<=n) 70 { 71 flag=false; 72 ssss.clear(); 73 for(int i=1;i<=(n-len+1);i++) 74 { 75 it=ssss.find(a[i]); 76 if(it!=ssss.end()) 77 continue; 78 dfs(i,1); 79 ssss.insert(a[i]); 80 } 81 if(!flag) 82 break; 83 len++; 84 } 85 cout<<endl; 86 } 87 return 0; 88 }