zoukankan      html  css  js  c++  java
  • Sequence one(hdu2610dfs+去重)

    题目:有一个数列N,和一个数字k,输出该数列的前k个子序列,如果k大于N的所有子序列,输出所有符合要求的序列,序列要求不能是递减序列

    比如:

    3 5

    1 3 2

    的前五个序列为

    1

    3

    2

    1 3

    1 2

    没有3 2 因为3 2 为递减的

    思路:dfs搜索,保存上一次选择的数和所选的数的下标,当选择下一个数的时候比较和上次所选择数的大小,大于等于的是符合条件的,符合条件的输出

    这里有三个剪枝:

    1.当选择每个序列第一个数的时候,前面如果有相同的数字,那么该数就不搜索,因为前一个选的数已经把他后面的数包含在内,在搜索是浪费

    2.当选择的数不是第一个数的时候,那么你选择的前一个数的下标到该数的下标之间,看有没重复的数,如果重复也不用搜索了

    注意:如果某个序列的子序列没找到解,说明比它长的子序列都没解,也不用搜了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int num[1001];
    int count_ = 0,len,n,p;
    bool flag = false;
    struct number
    {
        int num;
        int pos;
    }path[1001];
    
    bool check(int c,int e)
    {
        int i;
        for(i = c; i < e; i++)
        {
            if(num[i] == num[e])
                return false;
        }
        return true;
    }
    
    void dfs(int dep,int pos)
    {
        if(count_ >= p)
            return;
        if(dep == len)
        {
            count_++;
            flag = true;
            int i;
            for(i = 0; i < len-1; i++)
                printf("%d ",path[i].num);
            printf("%d
    ",path[i].num);
            return ;
        }
        int i;
        for(i = pos; i < n; i++)
        {
            if(dep == 0 || (dep != 0 && path[dep-1].num <= num[i]))
            {
                if(dep == 0 && !check(0,i) )
                    continue;
                if(dep != 0 && !check(path[dep-1].pos+1,i) )
                    continue;
                path[dep].num = num[i];
                path[dep].pos = i;
                dfs(dep+1,i+1);
            }
        }
        return ;
    }
    int main()
    {
        while(scanf("%d%d",&n,&p) != EOF)
        {
            int i;
            for(i = 0; i < n ; i++)
            {
                scanf("%d",&num[i]);
            }
            count_ = 0;
            for(i = 1; i < n; i++)
            {
                flag = false;
                len = i;
                dfs(0,0);
                if(!flag || (count_ >= p))
                    break;
            }
            printf("
    ");
        }
        return 0;
    }


  • 相关阅读:
    SPOJ GSS4 Can you answer these queries IV ——树状数组 并查集
    SPOJ GSS3 Can you answer these queries III ——线段树
    SPOJ GSS2 Can you answer these queries II ——线段树
    SPOJ GSS1 Can you answer these queries I ——线段树
    BZOJ 2178 圆的面积并 ——Simpson积分
    SPOJ CIRU The area of the union of circles ——Simpson积分
    HDU 1724 Ellipse ——Simpson积分
    HDU 1071 The area ——微积分
    HDU 4609 3-idiots ——FFT
    BZOJ 2194 快速傅立叶之二 ——FFT
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3214981.html
Copyright © 2011-2022 走看看