zoukankan      html  css  js  c++  java
  • [背包]JZOJ 3232 【佛山市选2013】排列

    Description

    一个关于n个元素的排列是指一个从{1, 2, …, n}到{1, 2, …, n}的一一映射的函数。这个排列p的秩是指最小的k,使得对于所有的i = 1, 2, …, n,都有p(p(…p(i)…)) = i(其中,p一共出现了k次)。

    例如,对于一个三个元素的排列p(1) = 3, p(2) = 2, p(3) = 1,它的秩是2,因为p(p(1)) = 1, p(p(2)) = 2, p(p(3)) = 3。

    给定一个n,我们希望从n!个排列中,找出一个拥有最大秩的排列。例如,对于n=5,它能达到最大秩为6,这个排列是p(1) = 4, p(2) = 5, p(3) = 2, p(4) = 1, p(5) = 3。

    当我们有多个排列能得到这个最大的秩的时候,我们希望你求出字典序最小的那个排列。对于n个元素的排列,排列p的字典序比排列r小的意思是:存在一个整数i,使得对于所有j < i,都有p(j) = r(j),同时p(i) < r(i)。对于5来说,秩最大而且字典序最小的排列为:p(1) = 2, p(2) = 1, p(3) = 4, p(4) = 5, p(5) = 3。
     

    Input

    输入的第一行是一个整数T(T <= 10),代表数据的个数。

    每个数据只有一行,为一个整数N。

    Output

    对于每个N,输出秩最大且字典序最小的那个排列。即输出p(1), p(2),…,p(n)的值,用空格分隔。
     

    Sample Input

    2
    5
    14

    Sample Output

    2 1 4 5 3
    2 3 1 5 6 7 4 9 10 11 12 13 14 8
     

    Data Constraint

    对于40%的数据,有1≤N≤100。

    对于所有的数据,有1≤N≤10000。

    分析

    稍作分析就可以发现这是要把一个正整数分为多个正整数,其最小公倍数最大的正整数组的最小字典序

    考虑到排列很难构造,那我们直接构造最小公倍数

    它必定是若干个质数的乘积

    那么题中的最小公倍数则可以表示为

    W=p1^c1*p2^c2*p3^c3…… p是质数 c是质数的指数,p之和不超过n

    如果比n小怎么办?直接在排列最前端补足1 2 3 4 5 6……

    那么可得f[i][j]为处理了第i个质数,和为j的最大最小公倍数(因为是质数直接乘)

    f[i][j]=f[i-1][j-w]*w w为质数或质数的幂

    至于答案,只需要用g[i][j]记录一下状态是从哪个状态转移过来的即可

    注意,f的值会非常大,可以用自然对数法,也可以直接用double(本题几乎无视精度问题)

    #include <iostream> 
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    typedef double ld;
    const int N=1e4+10;
    int prime[1310],cnt;
    bool b[N];
    int t,n;
    int from[1310][N],cunt,a[1310],acnt;
    ld f[1310][N],mx; 
    
    void Get_Prime() {
        for (int i=2;i<=10000;i++) {
            if (!b[i]) prime[++cnt]=i;
            int j=2*i;
            while (j<=10000) {
                b[j]=1;
                j+=i;
            }
        }
    }
    
    void Get(int last) {
        int dep=cnt;
        while (dep) {
            if (last-from[dep][last]) a[++acnt]=last-from[dep][last];
            last=from[dep][last];dep--;
        }
    }
    
    int main() {
        Get_Prime();
        for (scanf("%d",&t);t;t--) {
            scanf("%d",&n);
            if (n<5) {
                for (int i=2;i<=n;i++) printf("%d ",i);
                printf("1
    ");
                continue;
            }
            mx=0;
            for (int i=1;i<=cnt;i++)
                for (int j=0;j<=n;j++) f[i][j]=0;
            f[0][0]=1;
            for (int i=1;i<=cnt;i++) {
                int l=prime[i];
                for (int j=0;j<=n;j++) f[i][j]=f[i-1][j],from[i][j]=j;
                for (;l<=n;l*=prime[i]) {
                    for (int j=l;j<=n;j++)
                        if (f[i][j]<f[i-1][j-l]*1.0*l) {
                            f[i][j]=f[i-1][j-l]*1.0*l;
                            from[i][j]=j-l;
                        }
                }
            }
            ld mx=0;int last;
            for (int i=1;i<=n;i++)
                if (mx<f[cnt][i]) {
                    mx=f[cnt][i];
                    last=i;
                }
            for (int i=1;i<=n-last;i++) printf("%d ",i);
            cunt=n-last;acnt=0;
            Get(last);
            sort(a+1,a+acnt+1);
            for (int i=1;i<=acnt;i++) {
                for (int j=2;j<=a[i];j++) printf("%d ",j+cunt);
                printf("%d ",1+cunt);
                cunt+=a[i];
            }
            printf("
    ");
        }
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    SAP PI 如何实现消息定义查询
    EWM与ERP交互程序
    ITS Mobile Template interpretation failed. Template does not exist
    SAP Material Flow System (MFS) 物料流系统简介
    SAP EWM Table list
    EWM RF 屏幕增强
    SAP EWM TCODE list
    SAP扩展仓库管理(SAPEWM)在线研讨会笔记
    ERP与EWM集成配置ERP端组织架构(二)
    EWM RF(Radio Frequency)简介
  • 原文地址:https://www.cnblogs.com/mastervan/p/11107804.html
Copyright © 2011-2022 走看看