hdu 2610

Sequence one

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

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

好题:

判重很巧妙

重判,这里有两个重判,第一个重判是判断如果搜索的是子序列的第一个元素,那么判断从原始序列开始到当前位置是否已经出现过该元素,若出现过则之前肯定搜索过该元素,则放弃该元素的搜索。第二个重判,当搜索的不是子序列的第一个元素时,则判断子序列的前一个元素对应原始序列的位置,然后从该位置下一个元素开始到到当前搜索的位置之前判断该元素是否出现过,如果出现过,说明该子串出现过重复的,则放弃该元素。

dep代表 子串的长度,pos代表 原数组中的位置。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
using namespace std;
int n,p,a[1010],cnt,len;
bool flag;
struct line
{
      int num;
      int pos;
}path[1010];
bool check(int x,int y)
{
      for(int i=x;i<y;i++)
      {
            if(a[i]==a[y])
                  return false;
      }
      return true;
}
void dfs(int dep,int pos)
{
     if(cnt>=p)
            return ;
     if(dep==len)
     {
         cnt++;
         flag=true;
         for(int i=0;i<len-1;i++)
            printf("%d ",path[i].num);
         printf("%d\n",path[len-1].num);
         return ;
     }
     for(int i=pos;i<n;i++)
     {
           if(dep==0||path[dep-1].num<=a[i])
           {
                 if(dep==0&&!check(0,i))
                        continue;
                 if(dep!=0&&!check(path[dep-1].pos+1,i))
                        continue;
                 path[dep].num=a[i];
                 path[dep].pos=i;
                 dfs(dep+1,i+1);
           }
     }
}
int main()
{
      while(scanf("%d%d",&n,&p)!=EOF)
      {
          cnt=0;
          for(int i=0;i<n;i++)
                  scanf("%d",&a[i]);
          for(int i=1;i<=n;i++)
          {
               len=i;
               flag=false;
               dfs(0,0);
               if(!flag||cnt>=p)
                  break;
          }
          printf("\n");
      }
      return 0;
}

  

时间: 2024-10-12 21:16:01

hdu 2610的相关文章

HDU 2610 (自己完全找不到思路) Sequence one

搜索虐我千百遍,我待搜索...好吧,我还木有初恋 题意: 我开始理解题意就理解偏了,Orz 题中有n个元素构成的序列,求出前p个非递减子序列.子序列是先按长度排序的,然后按原序列先后位置排序的. 这里的非递减是指子序列中从左到右元素大小的值不减,对,就是这我理解错了. 如果p>所有符合要求的子序列的个数,那么输出所有的子序列 这道题完全是参照这个大神的博客的代码A过的 http://www.cnblogs.com/newpanderking/archive/2012/10/11/2719941.

50道hdu基础搜索总结(转)

Dfs: 大部分是直接递归枚举,即求满足约束条件下的解,虽不用剪枝,但也需要代码能力. 练习递归枚举的题目: 1241       Oil Deposits (dfs的连通块个数) 1016       Prime Ring Problem 1584       蜘蛛牌(简单dfs,简单的剪枝,还有人用DP做(???)) 1426       Sudoku Killer(练习递归的好题目 or Dancing links(???)) 2510       符号三角形(打表题,写写打表程序还是不错

HDU 4632 Palindrome subsequence (区间dp 容斥定理)

Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65535 K (Java/Others) Total Submission(s): 2610    Accepted Submission(s): 1050 Problem Description In mathematics, a subsequence is a sequence that can be derived

[最小表示法] hdu 2609 How many

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2609 How many Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1225    Accepted Submission(s): 476 Problem Description Give you n ( n < 10000) nec

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

[hdu 2102]bfs+注意INF

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2102 感觉这个题非常水,结果一直WA,最后发现居然是0x3f3f3f3f不够大导致的--把INF改成INF+INF就过了. #include<bits/stdc++.h> using namespace std; bool vis[2][15][15]; char s[2][15][15]; const int INF=0x3f3f3f3f; const int fx[]={0,0,1,-1};

HDU 3555 Bomb (数位DP)

数位dp,主要用来解决统计满足某类特殊关系或有某些特点的区间内的数的个数,它是按位来进行计数统计的,可以保存子状态,速度较快.数位dp做多了后,套路基本上都差不多,关键把要保存的状态给抽象出来,保存下来. 简介: 顾名思义,所谓的数位DP就是按照数字的个,十,百,千--位数进行的DP.数位DP的题目有着非常明显的性质: 询问[l,r]的区间内,有多少的数字满足某个性质 做法根据前缀和的思想,求出[0,l-1]和[0,r]中满足性质的数的个数,然后相减即可. 算法核心: 关于数位DP,貌似写法还是