顯然填的數是不降的。。。
然後把-1都扣出來,f[i][j]表示前i個-1填j的逆序數
然後分別對與每個點求出來他前面的比他大的和後面的比他小的數就可以了
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define MAX 10009
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define inf 0x7fffffff/2
using namespace std;
int n,a[MAX],p[MAX];
int k,t,big[MAX][101],small[MAX][101],f[MAX][101];
int main()
{
scanf("%d%d",&n,&k);
t=0;
rep(i,1,n)
{
scanf("%d",&a[i]);
if(a[i]==-1)
p[++t]=i;
}
rep(i,2,n)
rep(j,1,k)
{
big[i][j]=big[i-1][j];
if(a[i-1]>j)
big[i][j]++;
}
for(int i=n-1;i>=1;i--)
rep(j,1,k)
{
small[i][j]=small[i+1][j];
if(a[i+1]!=-1&&a[i+1]<j)
small[i][j]++;
}
memset(f,63,sizeof(f));
f[0][0]=0;
rep(i,1,k)
f[1][i]=big[p[1]][i]+small[p[1]][i];
rep(i,2,t)
rep(j,1,k)
rep(w,1,j)
f[i][j]=min(f[i][j],f[i-1][w]+big[p[i]][j]+small[p[i]][j]);
int ans=inf;
rep(i,1,k)
ans=min(ans,f[t][i]);
ans=((ans==f[n+1][k+1])?0:ans);
rep(i,1,n)
ans+=big[i][a[i]];
printf("%d\n",ans);
return 0;
}