HDU2610 Sequence one【DFS+剪枝】

Sequence one

Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1076 Accepted Submission(s): 435

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

Hint
Hint : You must make sure each subsequence in the subsequences is unique.

Author
yifenfei

Source
奋斗的年代

问题链接HDU2610 Sequence one
问题简述:在给定的序列中找到固定个数的递增的子序列。若子序列的总个数少于要求的个数,那么就把所有的子序列输出。需要注意每组测试样例输出的后面有一空行。
问题分析:用DFS来解决,需要使用剪枝来加速。
程序说明:(略)
参考链接:(略)
题记:(略)

AC的C++语言程序如下:

/* HDU2610 Sequence one */

#include <bits/stdc++.h>

using namespace std;

const int N = 1000 + 1;
int n, p, cnt, a[N], path[N];

void dfs(int cur, int pos, int len)
{
    if(n - cur < len - pos) return;     // 剪枝:剩余原串长度小于剩余搜索长度
    if(cnt >= p) return;        // 剪枝:搜索到p个元素
    if(pos == len) {
        cnt++;
        printf("%d", path[0]);
        for(int i = 1; i < len; i++)
            printf(" %d", path[i]);
        printf("\n");
        return;
    }
    for(int i = cur + 1; i <= n; i++) {
        if(pos > 0 && a[i] < path[pos - 1]) continue;
        int token = 0;
        for(int j = cur + 1; j < i; j++)
            if(a[j] == a[i]) {
                token = 1;
                break;
            }
        if(token) continue;
        path[pos] = a[i];
        dfs(i, pos + 1, len);
        if(cnt == p) return;
    }
}

int main()
{
    while(~scanf("%d%d", &n, &p)) {
        for(int i = 1; i <= n; i++) scanf("%d", &a[i]);

        cnt = 0;
        for(int i = 1; i <= n; i++) {
            int cnt2 = cnt;
            dfs(0, 0, i);
            if(cnt == cnt2 || cnt >= p) break;
        }
        printf("\n");
    }

    return 0;
}
原创文章 2323 获赞 2382 访问量 269万+

猜你喜欢

转载自blog.csdn.net/tigerisland45/article/details/105779766