HDU 2610 Sequence one
题目大意:在给定的序列中找到固定个数的递增的子序列,如果子序列的总个数少于要求的个数,那么就把所有的子序列输出即可。
题解:本来题目也不太看得懂,在别人的博客看了许久才懂,剪枝和判重也不大会,于是暂时先把它给看懂。一个有效的剪枝,一个子串如果不成立,那么比其大的子串显然不成立,所以剪枝。
#include <cstdio> #include <iostream> #include <cstdlib> #include <algorithm> using namespace std; int n,p,len,count_num; int num[1001]; bool flag; typedef struct { int n,pos; }Tem; Tem tem[1001]; bool check(int s,int e) { for(int i = s+1; i < e; i++) if(num[i]==num[e])return false; return true; } void print_sequence(int length) { for(int i = 0; i < length-1;i++) cout<<tem[i].n<<" "; cout<<tem[length-1].n<<endl; } void dfs(int dep,int pos) { if(count_num >= p)return; if(dep==len) { count_num++; flag = true; print_sequence(len); return; } for(int i=pos;i<n;i++) { if((dep!=0&&tem[dep-1].n<=num[i])||dep==0) { if(dep==0&&!check(-1,i)) continue; if(dep!=0&&!check(tem[dep-1].pos,i)) continue; tem[dep].n = num[i]; tem[dep].pos = i; dfs(dep+1,i+1); } } return; } int main() { while(cin>>n>>p) { for(int i=0;i<n;i++) cin>>num[i]; count_num = 0; for(int i = 1;i < n;i++) { flag=false; len = i; dfs(0,0); if(count_num>=p||!flag)break; } cout<<endl; } return 0; }
愿你出走半生,归来仍是少年