zoukankan      html  css  js  c++  java
  • 【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 }
  • 相关阅读:
    要坚持的好习惯
    Attribute与Property关系
    浅谈ES6中super关键字
    JS权威指南读书笔记(七)
    JS权威指南读书笔记(六)
    JS权威指南读书笔记(五)
    JS权威指南读书笔记(四)
    函数
    对象
    数值
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/6517914.html
Copyright © 2011-2022 走看看