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; }
Sometimes it s the very people who no one imagines anything of. who do the things that no one can imagine.