码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 2062 Subset sequence 数位dp,思路 难度:1

时间:2015-02-21 00:18:44      阅读:344      评论:0      收藏:0      [点我收藏+]

标签:

http://acm.hdu.edu.cn/showproblem.php?pid=2062

Subset sequence

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3569    Accepted Submission(s): 1802


Problem Description
Consider the aggregate An= { 1, 2, …, n }. For example, A1={1}, A3={1,2,3}. A subset sequence is defined as a array of a non-empty subset. Sort all the subset sequece of An in lexicography order. Your task is to find the m-th one.
 

 

Input
The input contains several test cases. Each test case consists of two numbers n and m ( 0< n<= 20, 0< m<= the total number of the subset sequence of An ).
 

 

Output
For each test case, you should output the m-th subset sequence of An in one line.
 

 

Sample Input
1 1 2 1 2 2 2 3 2 4 3 10
 

 

Sample Output
1 1 1 2 2 2 1 2 3 1
 
规律:
比如3个的,如果把每种深度视为一大格,那么对于任意深度d(start from 0),
*              第一个一定是空,剩下有n-d个没被使用的数字按照顺序排列,
1              且n-d个数字的小格高度相同
  *        明显,我们可以提前处理出这个高度
  2        第(n-1)层每个数字占1个高度
    *  第(n-2)层每个数字占2个高度,1个空格,1个数字
    3  第(n-3)层每个数字有5个高度,1个空格,2个数字
  3       ......
    *  第i层有:dis[i]=(n-1-i)*dis[i+1]+1
    2  所以 dis[i+1]=(dis[i]-1)/(n-1-i)
2             也就是dis[i]=(dis[i-1]-1)/(n-i)
  *       处理出来之后,一层层查找确定对应位上的数字即可
  1
    *
    3
  3
    *
    1
3
  *
  1
    *
    2
  2
    *
    1
 
#include <iostream>
#include <cstring>
using namespace std;
typedef unsigned long long ll;
int n;
ll m;
int bit[20],len;
bool used[21];
int fnd(int ind){
        int ind2=0;
        for(int i=1;i<21;i++){
                if(!used[i]){
                        if(ind==ind2)return i;
                        ind2++;
                }
        }
        return -1;
}
ll all;
ll dis[21];
int main(){
        while(cin>>n>>m){
                memset(used,0,sizeof(used));
                all =1;
                ll sub=1;
                for(int i=0;i<n;i++){
                        sub*=(n-i);
                        all+=sub;
                }

                for(int i=0;i<n;i++){
                        all--;
                        dis[i]=all/(n-i);
                        all/=(n-i);
                }
                len=0;
                for(int i=n;i>=1;i--,len++){
                        if(m==0){break;}
                        m--;
                        bit[len]=fnd(m/dis[len]);
                        used[bit[len]]=true;
                        m%=dis[len];
                }
                for(int i=0;i<len;i++){
                        cout<<bit[i]<<(i==len-1?‘\n‘:‘ ‘);
                }
        }
        return 0;
}

  

HDU 2062 Subset sequence 数位dp,思路 难度:1

标签:

原文地址:http://www.cnblogs.com/xuesu/p/4296787.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!