zoukankan      html  css  js  c++  java
  • [CC-SEABUB]Sereja and Bubble Sort

    [CC-SEABUB]Sereja and Bubble Sort

    题目大意:

    一个(n(nle100))个数的排列(A),有两种操作:

    1. 交换两个相邻元素;
    2. 等概率随机打乱整个序列。

    最多执行(k(kle10^{18}))次操作,使得最后逆序对数量尽可能小,求最后逆序对数量期望值。

    单个测试点(T(Tle100))组数据。

    思路:

    一个基本性质是每交换两个相邻元素都可以消去一个逆序对。

    一组询问的答案要么是直接通过交换消去所有的逆序对,要么是通过若干次随机打乱以后再通过交换相邻元素消去逆序对。

    对于第一种情况,直接求逆序对即可。答案为(min(cnt-k,0))

    对于第二种情况,显然打乱以后的排列与(A)本身无关,因此考虑动态规划预处理所有答案。

    (f[i][j][k])表示排列的长度为(i),有(j)个逆序对,再经过不超过(k)次操作后,逆序对个数的期望。

    (g[i][j])表示排列的长度为(i),再经过不超过(j)次操作后,逆序对个数的期望。

    (h[i][j])表示排列的长度为(i),逆序对个数为(j)的概率。

    转移是(g[i][j]=sum f[i][k][j] imes h[i][k])

    考虑不同取值的(k)如何转移。

    1. (kle j),在(j)步操作内就可以消去所有的逆序对,贡献为(0)
    2. (j<klelfloor j+g[i][j-1] floor),尽可能地交换,就算不能消去全部,期望也比打乱以后更优。贡献是(sum h[i][k] imes(k-j))
    3. 剩下的情况,重新打乱更优,贡献为(g[i][j-1])

    使用前缀和优化即可。

    预处理复杂度(mathcal O(n^4)),单次询问复杂度(mathcal O(nlog n))

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    typedef long long int64;
    inline int64 getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int64 x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    const int N=101,M=4951;
    int64 k;
    int n,a[N];
    double f[N][M],h[N][M],g[N][M];
    class FenwickTree {
    	private:
    		int val[N];
    		int lowbit(const int &x) const {
    			return x&-x;
    		}
    	public:
    		void reset() {
    			std::fill(&val[1],&val[n]+1,0);
    		}
    		int query(int p) const {
    			int ret=0;
    			for(;p;p-=lowbit(p)) ret+=val[p];
    			return ret;
    		}
    		void modify(int p) {
    			for(;p<=n;p+=lowbit(p)) val[p]++;
    		}
    };
    FenwickTree t;
    inline int calc() {
    	int ret=0;
    	t.reset();
    	for(register int i=n;i>=1;i--) {
    		ret+=t.query(a[i]);
    		t.modify(a[i]);
    	}
    	return ret;
    }
    int main() {
    	h[1][0]=1;
    	for(register int i=2;i<N;i++) {
    		for(register int j=0;j<i;j++) {
    			for(register int k=0;k<=(i-1)*(i-2)/2;k++) {
    				h[i][j+k]+=h[i-1][k];
    			}
    		}
    	}
    	double fac=1;
    	for(register int i=1;i<N;i++) {
    		fac*=i;
    		for(register int j=0;j<=i*(i-1)/2;j++) {
    			h[i][j]/=fac;
    		}
    	}
    	for(register int i=1;i<N;i++) {
    		for(register int j=1;j<=i*(i-1)/2;j++) {
    			f[i][j]=f[i][j-1]+h[i][j]*j;
    			h[i][j]+=h[i][j-1];
    		}
    	}
    	for(register int i=1;i<N;i++) {
    		const int m=i*(i-1)/2;
    		g[i][0]=f[i][m];
    		for(register int j=1;j<=m;j++) {
    			const int l=std::min(j+(int)g[i][j-1],m);
    			g[i][j]+=f[i][l]-f[i][j]-j*(h[i][l]-h[i][j]);
    			g[i][j]+=g[i][j-1]*(h[i][m]-h[i][l]);
    		}
    	}
    	for(register int T=getint();T;T--) {
    		n=getint(),k=getint();
    		for(register int i=1;i<=n;i++) a[i]=getint();
    		double ans=std::max(calc()-k,0ll);
    		if(k!=0) ans=std::min(ans,g[n][std::min(k-1,(int64)n*(n-1)/2)]);
    		printf("%f
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    WebService到底是什么?(转)
    C# 页面抓取获取快递信息
    SQL Server ->> 条件筛选做法之 -- IN(VALUE1,VALUE2,...)与INNER JOIN STRING_SPLIT()性能对比
    SQL Server ->> MSDB.DBO.AGENT_DATETIME函数从整型转时间日期格式
    Windows ->> Windows Server 2012打开管理添加“我的电脑”桌面图标途径
    Windows ->> Windows下安装MSI程序遇到2503和2502错误
    SQL Server ->> DAC(Dedicated Administrator Connection)专用管理员连接
    SQL Server ->> 高可用与灾难恢复(HADR)技术之 -- Transaction Replication(事务复制)
    SQL Server ->> ColumnStore Index(列存储索引)
    SQL Server ->> 使用Azure Active Directory Authentication连接到Azure SQL Database
  • 原文地址:https://www.cnblogs.com/skylee03/p/9432709.html
Copyright © 2011-2022 走看看