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;
}
posted @ 2014-02-10 18:06  forever97  阅读(223)  评论(0编辑  收藏  举报