BZOJ 1831 & 就是一个DP....

题意:

  比如说,4 2 1 3 3里面包含了5个逆序对:(4, 2), (4, 1), (4, 3), (4, 3), (2, 1)。 可惜的是,由于年代久远,这些数字里有一部分已经模糊不清了,为了方便记录,小可可用“-1”表示它们。比如说,4 2 -1 -1 3 可能原来是4 2 1 3 3,也可能是4 2 4 4 3,也可能是别的样子。 能不能推断出这些数字里最少能有多少个逆序对

SOL:

  一眼就觉得显然填的数字单调不降...也不想去证明了,感觉很对的样子就不想那么多...

  但是DP的实现上还是弱的一笔啊...最弱的就是DP了..唉...本来还想维护两棵线段树加加减减...

  被数据结构洗脑了...然而只要暴力维护就好了...日...

  双倍经验很开心

Code:

  

/*==========================================================================
# Last modified: 2016-03-16 20:57
# Filename: 2190.cpp
# Description: 
==========================================================================*/
#define me AcrossTheSky 
#include <cstdio> 
#include <cmath> 
#include <ctime> 
#include <string> 
#include <cstring> 
#include <cstdlib> 
#include <iostream> 
#include <algorithm> 
  
#include <set> 
#include <map> 
#include <stack> 
#include <queue> 
#include <vector> 
 
#define lowbit(x) (x)&(-x) 
#define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++) 
#define FORP(i,a,b) for(int i=(a);i<=(b);i++) 
#define FORM(i,a,b) for(int i=(a);i>=(b);i--) 
#define ls(a,b) (((a)+(b)) << 1) 
#define rs(a,b) (((a)+(b)) >> 1) 
#define getlc(a) ch[(a)][0] 
#define getrc(a) ch[(a)][1] 
 
#define maxn 100000 
#define maxm 100000 
#define pi 3.1415926535898 
#define _e 2.718281828459 
#define INF 1070000000 
using namespace std; 
typedef long long ll; 
typedef unsigned long long ull; 
 
template<class T> inline 
void read(T& num) { 
    bool start=false,neg=false; 
    char c; 
    num=0; 
    while((c=getchar())!=EOF) { 
        if(c=='-') start=neg=true; 
        else if(c>='0' && c<='9') { 
            start=true; 
            num=num*10+c-'0'; 
        } else if(start) break; 
    } 
    if(neg) num=-num; 
} 
/*==================split line==================*/ 
int a[10005],pos[10005];
int small[10005][105],big[10005][105],dp[10005][105];
int main(){
    int n,k,cnt=0;
    memset(big,0,sizeof(big));
    memset(small,0,sizeof(small));
    memset(dp,0x7f,sizeof(dp));
    int ans=INF;
    read(n); read(k);
    FORP(i,1,n){
        read(a[i]);
        if(a[i]==-1) pos[++cnt]=i;
    }
    FORP(i,2,n){
        FORP(j,1,k){
            big[i][j]=big[i-1][j];
            if(a[i-1]>j) big[i][j]++;
        }
    }
    FORM(i,n-1,1){
        FORP(j,1,k){
            small[i][j]=small[i+1][j];
            if(a[i+1]<j && a[i+1]!=-1) small[i][j]++;
        }
    }
    int num=0;
    FORP(i,1,n) num+=big[i][a[i]];
    FORP(i,1,k) dp[1][i]=big[pos[1]][i]+small[pos[1]][i];
    FORP(i,2,cnt)
    FORP(j,1,k)
    FORP(p,1,j)dp[i][j]=min(dp[i][j],dp[i-1][p]+big[pos[i]][j]+small[pos[i]][j]);
    FORP(i,1,k) ans=min(ans,dp[cnt][i]);
    ans=(ans==INF)?0:ans;
    printf("%d\n",ans+num);
    return 0;
}

 

posted @ 2016-03-21 11:58  YCuangWhen  阅读(197)  评论(0编辑  收藏  举报