| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
代码In Reply To:左偏树 Posted by:yc5_yc at 2012-07-06 17:38:49 const int NMax=1100;
inline int MIN(int a,int b)
{
return (a<b)?a:b;
}
struct node
{
int key,dist;
node *left,*right;
}*S[NMax],pool[NMax];
int N,K,A[NMax],A1[NMax];
void make(node *a,int K)
{
a->key=K;
a->dist=0;
a->left=a->right=NULL;
}
node* merge(node *a,node *b)
{
if(a==NULL) return b;
if(b==NULL) return a;
if(a->key<b->key) swap(a,b);
a->right=merge(a->right,b);
if(a->left==NULL || a->right->dist>a->left->dist)
swap(a->right,a->left);
if(a->right==NULL) a->dist=0;
else a->dist=a->right->dist+1;
return a;
}
int L,W[NMax],NUM[NMax],Cnt[NMax],TCnt[NMax],Non[NMax],TNon[NMax],La[NMax],F1[NMax][NMax],F2[NMax][NMax],dp[NMax];
int main()
{
while(scanf("%d%d",&N,&K),N)
{
for(int i=1;i<=N;i++) dp[i]=100000000;
for(int i=1;i<=N;i++)
scanf("%d",A1+i);
for(int i=1;i<=N;i++)
A[i]=A1[i]-i;
for(int I=1;I<N;I++)
{
L=1,S[1]=&pool[I];
make(S[1],A[I]);
W[1]=A[I],NUM[1]=1,Cnt[1]=1,TCnt[1]=A[I],TNon[1]=0,Non[1]=0,La[1]=0;
for(int i=I+1;i<=N;i++)
{
L++;
S[L]=&pool[i];
make(S[L],A[i]);
W[L]=A[i],NUM[L]=1,Cnt[L]=1,TCnt[L]=A[i],TNon[L]=0,Non[L]=0,La[L]=0;
while(L>1 && W[L]<W[L-1])
{
node *tmp=merge(S[L],S[L-1]);
Cnt[L-1]+=Cnt[L],TCnt[L-1]+=TCnt[L],TNon[L-1]+=TNon[L],Non[L-1]+=Non[L];
if((NUM[L]+1)/2+(NUM[L-1]+1)/2>(NUM[L]+NUM[L-1]+1)/2)
{
int tmp1=tmp->key;
tmp=merge(tmp->left,tmp->right);
Cnt[L-1]--,TCnt[L-1]-=tmp1;
Non[L-1]++,TNon[L-1]+=tmp1;
}
NUM[L-1]=NUM[L]+NUM[L-1];
S[L-1]=tmp;
W[L-1]=tmp->key;
L--;
}
F1[I][i]=La[L]=La[L-1]+(W[L]*Cnt[L]-TCnt[L]+TNon[L]-Non[L]*W[L]);
}
}
for(int i=1;i<=N;i++)
A[i]=-(A1[i]+i);
for(int I=1;I<N;I++)
{
L=1,S[1]=&pool[I];
make(S[1],A[I]);
W[1]=A[I],NUM[1]=1,Cnt[1]=1,TCnt[1]=A[I],TNon[1]=0,Non[1]=0,La[1]=0;
for(int i=I+1;i<=N;i++)
{
L++;
S[L]=&pool[i];
make(S[L],A[i]);
W[L]=A[i],NUM[L]=1,Cnt[L]=1,TCnt[L]=A[i],TNon[L]=0,Non[L]=0,La[L]=0;
while(L>1 && W[L]<W[L-1])
{
node *tmp=merge(S[L],S[L-1]);
Cnt[L-1]+=Cnt[L],TCnt[L-1]+=TCnt[L],TNon[L-1]+=TNon[L],Non[L-1]+=Non[L];
if((NUM[L]+1)/2+(NUM[L-1]+1)/2>(NUM[L]+NUM[L-1]+1)/2)
{
int tmp1=tmp->key;
tmp=merge(tmp->left,tmp->right);
Cnt[L-1]--,TCnt[L-1]-=tmp1;
Non[L-1]++,TNon[L-1]+=tmp1;
}
NUM[L-1]=NUM[L]+NUM[L-1];
S[L-1]=tmp;
W[L-1]=tmp->key;
L--;
}
F2[I][i]=La[L]=La[L-1]+(W[L]*Cnt[L]-TCnt[L]+TNon[L]-Non[L]*W[L]);
}
}
for(int i=1;i<=K;i++)
{
dp[0]=0;
for(int j=N;j>=1;j--)
{
for(int k=0;k<j;k++)
dp[j]=MIN(dp[j],dp[k]+MIN(F1[k+1][j],F2[k+1][j]));
}
}
printf("%d\n",dp[N]);
}
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator