【BZOJ】1831: [AHOI2008]逆序对

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1831


考虑$-1$的位置上填写的数字一定是不降的。

令${f[i][j]}$表示$DP$到了第$i$位,最后一个$-1$上填的数字是$j$的最少逆序对数量。

如果当前位置是$-1$:

${f[i][j]=minleft { f[i-1][x] |xleq j ight }+ma[i][j+1]+mi[i][j-1]}$

如果当前位是确定的数字。
${f[i][j]=f[i-1][j]+ma[i][j+1]}$

其中${ma[i][j]}$表示在给定数组第$i$位之前的数字中大于等于$j$的数字的数量,${mi[i][j]}$表示在给定数组第$i$位之后的数字中小于等于$j$的数字的数量。

${ma,mi}$数组用树状数组维护一下即可。


 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<vector>
 5 #include<cstdlib>
 6 #include<cmath>
 7 #include<cstring>
 8 using namespace std;
 9 #define maxn 10010
10 #define llg long long 
11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
12 llg n,m,f[maxn][110],val[maxn],V[maxn];
13 llg c[maxn];
14 
15 llg lowbit(llg x){return x&-x;}
16 
17 void add(llg x,llg v){for (;x<=m;x+=lowbit(x)) val[x]+=v;}
18 
19 llg sum(llg x){llg tot=0; for (;x>0;x-=lowbit(x)) tot+=val[x]; return tot;}
20 
21 void add_(llg x,llg v){for (;x<=m;x+=lowbit(x)) V[x]+=v;}
22 
23 llg sum_(llg x){llg tot=0; for (;x>0;x-=lowbit(x)) tot+=V[x]; return tot;}
24 
25 int main()
26 {
27     yyj("bzoj1831");
28     cin>>n>>m;
29     for (llg i=0;i<=n;i++)
30         for (llg j=0;j<=m;j++)
31             f[i][j]=0x7fffffff;
32     for (llg i=1;i<=n;i++) 
33     {
34         scanf("%lld",&c[i]);
35         if (c[i]!=-1) add_(c[i],1);
36     }
37     f[0][0]=0;
38     for (llg i=1;i<=n;i++)
39     {
40         if (c[i]!=-1)
41         {
42             for (llg j=0;j<=m;j++) f[i][j]=f[i-1][j]+sum(m)-sum(c[i]);
43             add_(c[i],-1);
44             add(c[i],1);
45         }
46         else
47         {
48             llg mi=f[i-1][0];
49             for (llg j=1;j<=m;j++)
50             {
51                 mi=min(f[i-1][j],mi);
52                 f[i][j]=mi+sum(m)-sum(j)+sum_(j-1);
53             }
54         }
55     }
56     llg ans=0x7fffffff;
57     for (llg i=0;i<=m;i++) ans=min(ans,f[n][i]);
58     cout<<ans;
59     return 0;
60 }
原文地址:https://www.cnblogs.com/Dragon-Light/p/6517914.html