zoukankan      html  css  js  c++  java
  • 洛谷 P3672 小清新签到题 [DP 排列]

    传送门

    题意:给定自然数n、k、x,你要求出第k小的长度为n的逆序对对数为x的1~n的排列

    $n le 300, k le 10^13$


    一下子想到hzc讲过的DP

    从小到大插入,后插入不会对前插入造成影响,$f[i][j]$表示$1..n$排列$j$个逆序对的方案数,枚举插在哪里

    然后从前向后选择满足要求的字典序最小的构造就行了

    一开始没注意$DP$方程是$O(n^4)$的T了一次,以后一定要跑一下极限数据

    加上前缀和优化

    然后会爆long long,但我们只关心与k相比大小,所以$>k$变成$k+1$就行了

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <ctime>
    using namespace std;
    typedef long long ll;
    const int N=301, M=N*(N-1)/2;
    inline ll read(){
        char c=getchar();ll x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
        return x*f;
    }
    
    int n, x, m, a[N], vis[N];
    ll f[N][M], k, s[2][M];
    void dp(){
        f[0][0]=1;
        int p=0;
        for(int i=0; i<=m; i++) s[p][i]=1;
        for(int i=1; i<=n; i++, p^=1)
            for(int j=0; j<=m; j++) { 
                int l=max(0, j-(i-1)), r=j;
                ll _= l==0 ? s[p][r] : s[p][r]-s[p][l-1];
                f[i][j]= _>k ? k+1 : _;
    
                s[p^1][j]=f[i][j];
                if(j!=0) s[p^1][j]+= s[p^1][j-1];
            }
    }
    int main(){
        //freopen("in","r",stdin);
        n=read(); k=read(); x=read();
        m=x;
        dp();
        //printf("
    %lf
    ", (double)clock()/CLOCKS_PER_SEC);
        for(int i=n; i>=1; i--) { 
            ll cnt=0;
            for(int j=1; j<=n; j++) if(!vis[j]) { 
                int c=j-1;
                for(int t=1; t<j; t++) c-= vis[t];
                if(f[i-1][x-c] + cnt>= k) {a[n-i+1]=j; vis[j]=1; x-= c; k-= cnt; break;}
                cnt+= f[i-1][x-c];
            }
        }
        for(int i=1; i<=n; i++) printf("%d ",a[i]);
        //printf("
    %lf", (double)clock()/CLOCKS_PER_SEC);
    }
  • 相关阅读:
    Java多态性理解
    多态详解
    public static void main(String[] args){}函数诠释
    继承、封装
    面向对象的理解
    重载与构造函数的解析
    冒泡排序及二分查找
    数组总结之补充
    计算机中如何表示数字-07IEEE754浮点数标准
    synchronized 和ReentrantLock
  • 原文地址:https://www.cnblogs.com/candy99/p/6582699.html
Copyright © 2011-2022 走看看