[AHOI2008] 逆序对
我们可以很容易的推断出$-1$是单调不降的,若$i>j$且$a_i$与$a_j$都没有填数,若填完之后$a_i>a_j$或者$a_i<a_j$,则对答案产生影响的只在$[i,j]$之间,则$a_i<a_j$对答案产生的贡献更小,则其实每个不同位置的$-1$其实是互不影响的,所以就可以用$dp$实现
设$dp(i,j)$表示这是从右往左数第$i$个$-1$,这里填j的最小逆序对数(这里的逆序对是只与$-1$有关的,其他的单算)
则$dp(i,j)=min(dp(i-1,p)+在第i个-1左面不是-1的对此数新产生的逆序对数+此数填后对右面产生的贡献) (j \leq p)$
我们可以用线段树维护逆序对,时间复杂度:$O(n\times k^2)$
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
inline int read(){
int f=,ans=;char c;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){ans=ans*+c-'';c=getchar();}
return f*ans;
}
int n,k,a[],cnt[],ans[];
void add(int k,int l,int r,int x,int y){
if(x>y) return ;
if(x<=l&&r<=y){ans[k]++;return;}
int mid=l+r>>;
if(x<=mid) add(k<<,l,mid,x,y);
if(mid<y) add(k<<|,mid+,r,x,y);
ans[k]=ans[k<<]+ans[k<<|];
return;
}
int query(int k,int l,int r,int x,int y){
if(x>y) return ;
if(x<=l&&r<=y) return ans[k];
int mid=l+r>>,res=;
if(x<=mid) res+=query(k<<,l,mid,x,y);
if(mid<y) res+=query(k<<|,mid+,r,x,y);
return res;
}
int cost[][],sum,dp[][],tot,minn,inf=<<-;
int main(){
minn=inf;
memset(dp,/,sizeof(dp));
n=read(),k=read();
for(int i=;i<=n;i++){
a[i]=read();
if(a[i]==-)
cnt[++cnt[]]=i;
}
for(int i=;i<=n;i++){
for(int j=;j<=k;j++){
cost[i][j]=cost[i-][j];
if(j<=a[i]) cost[i][j]++;
}
}
for(int i=;i<=k;i++) dp[][i]=;
for(int i=n;i>=;i--){
if(a[i]!=-){
sum+=query(,,k,,a[i]-);
add(,,k,a[i],a[i]);
}else{
tot++;
for(int j=;j<=k;j++){
for(int p=j;p<=k;p++){
dp[tot][j]=min(dp[tot-][p]+query(,,k,,j-)+cost[i][j+],dp[tot][j]);
if(tot==cnt[]) minn=min(minn,dp[tot][j]);
}
}
}
}
if(minn==inf) cout<<sum;
else cout<<sum+minn;
}
[AHOI2008] 逆序对的更多相关文章
- BZOJ1831: [AHOI2008]逆序对
1831: [AHOI2008]逆序对 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 341 Solved: 226[Submit][Status] ...
- 【BZOJ1831】[AHOI2008]逆序对(动态规划)
[BZOJ1831][AHOI2008]逆序对(动态规划) 题面 BZOJ 洛谷 题解 显然填入的数拎出来是不降的. 那么就可以直接大力\(dp\). 设\(f[i][j]\)表示当前填到了\(i\) ...
- bzoj1831: [AHOI2008]逆序对(DP+双精bzoj1786)
1831: [AHOI2008]逆序对 Description 小可可和小卡卡想到Y岛上旅游,但是他们不知道Y岛有多远.好在,他们找到一本古老的书,上面是这样说的: 下面是N个正整数,每个都在1~K之 ...
- BZOJ1786: [Ahoi2008]Pair 配对/1831: [AHOI2008]逆序对
这两道题是一样的. 可以发现,-1变成的数是单调不降. 记录下原有的逆序对个数. 预处理出每个点取每个值所产生的逆序对个数,然后dp转移. #include<cstring> #inclu ...
- 【BZOJ】1831: [AHOI2008]逆序对
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1831 考虑$-1$的位置上填写的数字一定是不降的. 令${f[i][j]}$表示$DP$到 ...
- 【[AHOI2008]逆序对】
被锤爆了 被这个题搞得自闭了一上午,觉得自己没什么前途了 我又没有看出来这个题的一个非常重要的性质 我们填进去的数一定是单调不降的 首先如果填进去的数并不是单调不降的,那么填进去本身就会产生一些逆序对 ...
- 洛谷 P4280 bzoj1786 [AHOI2008]逆序对(dp)
题面 luogu bzoj 题目大意: 给你一个长度为\(n\)的序列,元素都在\(1-k\)之间,有些是\(-1\),让你把\(-1\)也变成\(1-k\)之间的数,使得逆序对最多,求逆序对最少是多 ...
- [AHOI2008]逆序对(dp)
小可可和小卡卡想到Y岛上旅游,但是他们不知道Y岛有多远.好在,他们找到一本古老的书,上面是这样说的: 下面是N个正整数,每个都在1~K之间.如果有两个数A和B,A在B左边且A大于B,我们就称这两个数为 ...
- BZOJ 1831: [AHOI2008]逆序对
题目大意: 给出一个序列,有几个位置上的数字任意.求最小的逆序对数. 题解: 自己决定放置的数一定是单调不降的.不然把任意两个交换一下就能证明一定会增加逆序对. 然后就可以DP了,f[i][j]表示第 ...
随机推荐
- Python学习笔记(一)一一一环境安装错误总结
第三方库安装 1 windows存在多个版本的python,pip安装Python库失败 解决方案:进入对应官网下载安装包,步骤:1 下载安装包到C:\Python36\Lib\site-pack ...
- Python教程:Python中的for 语句
Python 中的 for 语句与你在 C 或 Pascal 中可能用到的有所不同. Python教程 中的 for 语句并不总是对算术递增的数值进行迭代(如同 Pascal),或是给予用户定义迭代步 ...
- 142. O(1) Check Power of 2【LintCode by java】
Description Using O(1) time to check whether an integer n is a power of 2. Example For n=4, return t ...
- Python3 Tkinter-Frame
1.创建 from tkinter import * root=Tk() for fm in ['red','blue','yellow','green','white','black']: Fram ...
- Linux 150命令之 文件和目录操作命令 cd pwd cp mv touch
cd 切换目录 cd 目录 [root@mysql ~]# cd / [root@mysql /]# ls application bin class dev home lib64 media nfs ...
- 2.hadoop基本配置,本地模式,伪分布式搭建
2. Hadoop三种集群方式 1. 三种集群方式 本地模式 hdfs dfs -ls / 不需要启动任何进程 伪分布式 所有进程跑在一个机器上 完全分布式 每个机器运行不同的进程 2. 服务器基本配 ...
- 环境变量PATH
一.举例 我在用户主文件夹执行命令“ls”,会在屏幕显示该文件夹下的所有文件.然而,ls的完整文件名为“/bin/ls”,按道理我不在/bin下要想执行ls命令必须输入“/bin/ls”,但我仅仅需要 ...
- Thunder团队Beta周贡献分规则
小组名称:Thunder 项目名称:i阅app 组长:王航 成员:李传康.翟宇豪.邹双黛.苗威.宋雨.胡佑蓉.杨梓瑞 分配规则 规则1:基础分,拿出总分的20%(8分)进行均分,剩下的80%(32分) ...
- Java容器之List接口
List 接口: 1. List 接口是 Collection 的子接口,实现 List 接口的容器类中的元素是有顺序的,而且可以重复: 2. List 容器中的元素都对应一个整数型的序号记载其在容器 ...
- Java 二维数组
在 Java 中,二维数组与一维数组一样,但是不同于 C 中的二维数组: 1. 在 Java 中,二维数组可以看成是以数组为元素的数组,例如: int a[][] = {{1,2},{3,4,5,6 ...