zoukankan      html  css  js  c++  java
  • HDU 2062 Subset sequence 数位dp,思路 难度:1

    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?'
    ':' ');
                    }
            }
            return 0;
    }
    

      

  • 相关阅读:
    Day9
    Day9
    Day9
    洛谷 P1896 [SCOI2005]互不侵犯
    洛谷 P1879 [USACO06NOV]玉米田Corn Fields
    Day9
    最大m段子段和 Day9
    jsp内置对象-application对象
    jsp内置对象-session对象
    jsp内置对象-response对象
  • 原文地址:https://www.cnblogs.com/xuesu/p/4296787.html
Copyright © 2011-2022 走看看