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;
}