[CC-SEABUB]Sereja and Bubble Sort
[CC-SEABUB]Sereja and Bubble Sort
题目大意:
一个\(n(n\le100)\)个数的排列\(A\),有两种操作:
- 交换两个相邻元素;
- 等概率随机打乱整个序列。
最多执行\(k(k\le10^{18})\)次操作,使得最后逆序对数量尽可能小,求最后逆序对数量期望值。
单个测试点\(T(T\le100)\)组数据。
思路:
一个基本性质是每交换两个相邻元素都可以消去一个逆序对。
一组询问的答案要么是直接通过交换消去所有的逆序对,要么是通过若干次随机打乱以后再通过交换相邻元素消去逆序对。
对于第一种情况,直接求逆序对即可。答案为\(\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]\times h[i][k]\)。
考虑不同取值的\(k\)如何转移。
- \(k\le j\),在\(j\)步操作内就可以消去所有的逆序对,贡献为\(0\);
- \(j<k\le\lfloor j+g[i][j-1]\rfloor\),尽可能地交换,就算不能消去全部,期望也比打乱以后更优。贡献是\(\sum h[i][k]\times(k-j)\);
- 剩下的情况,重新打乱更优,贡献为\(g[i][j-1]\)。
使用前缀和优化即可。
预处理复杂度\(\mathcal O(n^4)\),单次询问复杂度\(\mathcal O(n\log 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\n",ans);
}
return 0;
}
[CC-SEABUB]Sereja and Bubble Sort的更多相关文章
- Java中的经典算法之冒泡排序(Bubble Sort)
Java中的经典算法之冒泡排序(Bubble Sort) 神话丿小王子的博客主页 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一 ...
- Bubble Sort (5775)
Bubble Sort Problem Description P is a permutation of the integers from 1 to N(index starting from ...
- Bubble Sort [ASM-MIPS]
# Program: Bubble sort # Language: MIPS Assembly (32-bit) # Arguments: 5 unordered numbers stored in ...
- HDU 5775 Bubble Sort(冒泡排序)
p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...
- 2016 Multi-University Training Contest 4 Bubble Sort(树状数组模板)
Bubble Sort 题意: 给你一个1~n的排列,问冒泡排序过程中,数字i(1<=i<=n)所到达的最左位置与最右位置的差值的绝对值是多少 题解: 数字i多能到达的最左位置为min(s ...
- 快速幂取模 POJ 3761 bubble sort
题目传送门 /* 题意:求冒泡排序扫描k次能排好序的全排列个数 数学:这里有一个反序列表的概念,bj表示在j左边,但大于j的个数.不多说了,我也是看网上的解题报告. 详细解释:http://blog. ...
- 冒泡排序(Bubble Sort)
常见的排序算法有Bubble Sort.Merge Sort.Quick Sort 等,所有排序算的基本法思想都是把一个无限大的数据规模通过算法一步步缩小,指导最后完成排序. 这里分享一下Buuble ...
- [算法] 冒泡排序 Bubble Sort
冒泡排序(Bubble Sort,台湾另外一种译名为:泡沫排序)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没 ...
- HDU 5775 Bubble Sort (线段树)
Bubble Sort 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5775 Description P is a permutation of t ...
随机推荐
- 天梯赛 L2-20 功夫传人 (深搜)
一门武功能否传承久远并被发扬光大,是要看缘分的.一般来说,师傅传授给徒弟的武功总要打个折扣,于是越往后传,弟子们的功夫就越弱-- 直到某一支的某一代突然出现一个天分特别高的弟子(或者是吃到了灵丹.挖到 ...
- 利用Addon Domain和A记录使两个域名同时指向同一个网站
今天碰到这样的需求:已有网站A.com, 以及新注册的域名B.net, 现需要将B.net指向与A.com相同的内容. 这里提出的方法是在空间后台添加Addon domain, 以及在域名B.net后 ...
- G6踩坑日记
用G6去完成一整个图例的时候,当包裹它的容器满足不了包裹的需求时,我们就需要引入缩略图来解决问题了 缩略图使用方式很简单 引入插件配置就可以了 当我们使用多张图片进行绘图(G6支持使用图片进行构图,原 ...
- 关于SQLite3 编译及交叉编译的一些问题
from : http://blog.sina.com.cn/s/blog_5f2e119b0101ibwn.html SQLite3 (http://www.sqlite.org)是一个非常强大的小 ...
- static作用(修饰函数、局部变量、全局变量)转自http://www.cnblogs.com/stoneJin/archive/2011/09/21/2183313.html
static作用(修饰函数.局部变量.全局变量) 在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条. (1)先来介绍它的第一条也是最重要的一条:隐藏. 当我们同时编译多个文件 ...
- Nginx实现404页面的几种方法【转】
一个网站项目,肯定是避免不了404页面的,通常使用Nginx作为Web服务器时,有以下集中配置方式,一起来看看. 第一种:Nginx自己的错误页面 Nginx访问一个静态的html 页面,当这个页面没 ...
- mysql开启GTID跳过错误的方法【转】
1.数据库版本 MySQL> select version() -> ;+-------------------------------------------+| version( ...
- Python编程规范精简版
用四个空格缩进,不要用tab键:四个空格是在较小缩进(可以允许更大的嵌套深度)和较大缩进(可读性更好)之间的一个很好的折中.制表符会带来混乱,最好不要使用: 包装行保证每行不超过79个字符:这对那些使 ...
- 创建 dblink
目的:oracle中跨数据库查询 两台数据库服务器db_A(本地)和db_B(远程192.168.1.100),db_A下用户user_a 需要访问到db_B下user_b的数据解决:查询 ...
- 配置OpenCV+VS2013环境
配置OpenCV+VS2013环境 准备工作 win7系统 下载opencv的windows编译版 安装vs2013 express 设定环境变量 按windows窗键输入path,选择第二个结果编辑 ...