被锤爆了

被这个题搞得自闭了一上午,觉得自己没什么前途了

我又没有看出来这个题的一个非常重要的性质

我们填进去的数一定是单调不降的

首先如果填进去的数并不是单调不降的,那么填进去本身就会产生一些逆序对,感性理解好像是单调不降更优,这里还是严谨证明一下吧

考虑一下树状数组求逆序对的过程,显然就是求出每一个数前面有多少个比它大的数

这张图好丑啊

设\(A<B\),\(x\)表示那段绿色区间里大于\(A\)的数,\(y\)表示绿色区间里大于\(B\)的数,\(a\)表示蓝色区间里大于\(A\)的数,\(b\)表示蓝色区间里大于\(B\)的数

这个时候我们如果用树状数组来统计一下答案的话,\(A,B\)的贡献就是\(x+y+b\)

如果交换一下\(A\)和\(B\)的位置,那么这个时候答案就会变成\(x+a+y+1\)

非常显然的是\(b<=a\),所以可以得出\(x+y+b<x+a+y+1\),所以不交换更优

之后有了这个性质,我们就可以做一个\(dp\)了,设\(dp[i][j]\)表示填到了\(i\)位置,最靠后的一个\(-1\)位置填了\(j\)这个时候的最小逆序对是多少

就可以一边树状数组一边\(dp\)了

复杂度\(O(nklogk)\)

代码

#include<iostream>
#include<cstring>
#include<cstdio>
#define LL long long
#define lowbit(x) ((x)&(-x))
#define re register
#define maxn 100005
#define min(a,b) ((a)<(b)?(a):(b))
inline int read()
{
char c=getchar();
int x=0,r=1;
while(c<'0'||c>'9')
{
if(c=='-') r=-1;
c=getchar();
}
while(c>='0'&&c<='9')
x=(x<<3)+(x<<1)+c-48,c=getchar();
return x*r;
}
LL c[105];
int n,m;
LL ans;
LL dp[maxn][101];
LL mx[101];
int pre[maxn];
int a[maxn];
int beh[maxn][101];
inline void add(int x)
{
for(re int i=x;i<=m;i+=lowbit(i)) c[i]++;
}
inline LL ask(int x)
{
LL now=0;
for(re int i=x;i;i-=lowbit(i)) now+=c[i];
return now;
}
int main()
{
int cnt=0;
n=read(),m=read();
for(re int i=1;i<=n;i++)
{
a[i]=read();
if(a[i]==-1&&!cnt) cnt=i;
pre[i]=pre[i-1]+(a[i]==-1);
}
if(!cnt) cnt=n+1;
for(re int i=1;i<cnt;i++)
{
ans+=ask(m)-ask(a[i]);
add(a[i]);
}
if(cnt==n+1)
{
std::cout<<ans;
return 0;
}
for(re int i=n;i;i--)
{
for(re int j=1;j<=m;j++)
beh[i][j]=beh[i+1][j];
if(a[i]==-1) continue;
for(re int j=a[i];j<=m;j++) beh[i][j]++;
}
memset(dp,20,sizeof(dp));
for(re int i=1;i<=m;i++)
dp[cnt][i]=ans+ask(m)-ask(i)+beh[cnt][i-1];
memset(mx,20,sizeof(mx));
for(re int j=1;j<=m;j++)
mx[j]=min(mx[j-1],dp[cnt][j]);
for(re int i=cnt+1;i<=n;i++)
{
if(a[i]!=-1)
{
LL now=ask(m)-ask(a[i]);
for(re int j=1;j<=m;j++)
dp[i][j]=now+dp[i-1][j];
add(a[i]);
}
else
{
for(re int j=1;j<=m;j++)
{
LL now=ask(m)-ask(j);
dp[i][j]=mx[j]+now+beh[i][j-1];
}
}
memset(mx,20,sizeof(mx));
for(re int j=1;j<=m;j++)
mx[j]=min(mx[j-1],dp[i][j]);
}
LL Ans=0x7ffffffff;
for(re int i=1;i<=m;i++)
Ans=min(Ans,dp[n][i]);
std::cout<<Ans;
return 0;
}

【[AHOI2008]逆序对】的更多相关文章

  1. BZOJ1831: [AHOI2008]逆序对

    1831: [AHOI2008]逆序对 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 341  Solved: 226[Submit][Status] ...

  2. 【BZOJ1831】[AHOI2008]逆序对(动态规划)

    [BZOJ1831][AHOI2008]逆序对(动态规划) 题面 BZOJ 洛谷 题解 显然填入的数拎出来是不降的. 那么就可以直接大力\(dp\). 设\(f[i][j]\)表示当前填到了\(i\) ...

  3. bzoj1831: [AHOI2008]逆序对(DP+双精bzoj1786)

    1831: [AHOI2008]逆序对 Description 小可可和小卡卡想到Y岛上旅游,但是他们不知道Y岛有多远.好在,他们找到一本古老的书,上面是这样说的: 下面是N个正整数,每个都在1~K之 ...

  4. BZOJ1786: [Ahoi2008]Pair 配对/1831: [AHOI2008]逆序对

    这两道题是一样的. 可以发现,-1变成的数是单调不降. 记录下原有的逆序对个数. 预处理出每个点取每个值所产生的逆序对个数,然后dp转移. #include<cstring> #inclu ...

  5. 【BZOJ】1831: [AHOI2008]逆序对

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1831 考虑$-1$的位置上填写的数字一定是不降的. 令${f[i][j]}$表示$DP$到 ...

  6. [AHOI2008] 逆序对

    link 我们可以很容易的推断出$-1$是单调不降的,若$i>j$且$a_i$与$a_j$都没有填数,若填完之后$a_i>a_j$或者$a_i<a_j$,则对答案产生影响的只在$[i ...

  7. 洛谷 P4280 bzoj1786 [AHOI2008]逆序对(dp)

    题面 luogu bzoj 题目大意: 给你一个长度为\(n\)的序列,元素都在\(1-k\)之间,有些是\(-1\),让你把\(-1\)也变成\(1-k\)之间的数,使得逆序对最多,求逆序对最少是多 ...

  8. [AHOI2008]逆序对(dp)

    小可可和小卡卡想到Y岛上旅游,但是他们不知道Y岛有多远.好在,他们找到一本古老的书,上面是这样说的: 下面是N个正整数,每个都在1~K之间.如果有两个数A和B,A在B左边且A大于B,我们就称这两个数为 ...

  9. BZOJ 1831: [AHOI2008]逆序对

    题目大意: 给出一个序列,有几个位置上的数字任意.求最小的逆序对数. 题解: 自己决定放置的数一定是单调不降的.不然把任意两个交换一下就能证明一定会增加逆序对. 然后就可以DP了,f[i][j]表示第 ...

随机推荐

  1. Entity FreamWork框架

    实体框架 (Entity Framework) 1.是微软以ADO.Net为基础所发展出来的对象关系对应(O/R Mapping)解决方案. 2.实体框架Entity Framework是ADO.Ne ...

  2. System.Web.HttpException: 请求在此上下文中不可用

    转自:https://www.cnblogs.com/wangguowen27/archive/2013/05/12/IIS_itcast_win7.html 问题:Web应用程序池配置错误造成的,这 ...

  3. 浅谈Android项目----JSON解析(4种解析技术详解)

    json简介 1.概念:json全称是javaScript object Notation,是一种并轻量级的数据交换格式. 2.特点: 1.本质就是具有特定格式的字符串 2.json完全独立于编程语言 ...

  4. 手把手教你写一个RPC

    1.1 RPC 是什么 定义:RPC(Remote Procedure Call Protocol)--远程过程调用协议 ,RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数 ...

  5. [LeetCode] Add Two Numbers题解

    Add Two Numbers: You are given two non-empty linked lists representing two non-negative integers. Th ...

  6. <meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">的作用

    本人对该标签理解不深,这里是复制了穆乙的文章:如果有人进来看到这篇文章,请按此https://www.cnblogs.com/pigtail/archive/2013/03/15/2961631.ht ...

  7. 洛谷 P2469 [SDOI2010]星际竞速 解题报告

    题目描述 10年一度的银河系赛车大赛又要开始了.作为全银河最盛大的活动之一,夺得这个项目的冠军无疑是很多人的梦想,来自杰森座α星的悠悠也是其中之一. 赛车大赛的赛场由N颗行星和M条双向星际航路构成,其 ...

  8. drupal7 profile2模块获取个人信息

    一.问题背景: 用profile2模块,扩展个人信息,增加了“手机号”等信息,一些地方想要获取当前用户的手机号 二.解决办法: 用profile2自带的方法:profile2_load_by_user ...

  9. 在ES6中如何优雅的使用Arguments和Parameters

      原文地址:how-to-use-arguments-and-parameters-in-ecmascript-6 ES6是最新版本的ECMAScript标准,而且显著的改善了JS里的参数处理.我们 ...

  10. Qt Quick程序的发布

    要将程序发布出去,首先需要使用release方式编译程序,然后将生成的.exe可执行文件和需要的库文件发在一起打包进行发布. 要确定需要哪些动态库文件,可以直接双击.exe文件,提示缺少那个dll文件 ...