bzoj1484: [HNOI2009]通往城堡之路

神贪心。。。

b[i]=a[1]-(n-1)*d;

每次找价值最大的k

使b[k]~b[n]都++

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 6000
#define ll long long
inline long long min(long long x, long long y) {return x<y?x:y;};
inline long long max(long long x, long long y) {return x>y?x:y;};
inline long long ABS(long long x) {return x<0?-x:x;};
ll a[maxn];
ll b[maxn];
int n;
ll now=0,pp,maxx=-0x3fffffffffffffLL,jj,up=0x3fffffffffffffLL;
ll d,ans;
int m,i;
int main(){
    scanf("%d",&m);
   while(m--){
    scanf("%d%lld",&n,&d);
    for(i=1;i<=n;i++)scanf("%lld",&a[i]);
    b[1]=a[1];
    for(i=2;i<=n;i++)b[i]=b[i-1]-d;
    if(a[1]+(n-1)*d<a[n]||a[n]<a[1]-(n-1)*d){
      printf("impossible\n");  
    }else{
        ans=0;
        for(;a[n]!=b[n];){ 
            int j;
            now=0,maxx=-0x3ffffffffffffffLL,jj=0,up=0x3fffffffffffffLL;
            for( j=n;j>=2;j--){
                if(b[j]>=a[j])now--;
                else now++,up=min(up,a[j]-b[j]);   
                if(now>maxx&&b[j]<b[j-1]+d){
                  maxx=now;
                  jj=j;
                  pp=up;
                }
            }
            pp=min(pp,b[jj-1]+d-b[jj]);
            for(j=jj;j<=n;j++)b[j]+=pp;
        }
        for(i=1;i<=n;i++)ans+=ABS(b[i]-a[i]);
        printf("%lld\n",ans);
    }  
}
     
}

 

posted @ 2014-03-31 21:17  wangyucheng  阅读(348)  评论(0编辑  收藏  举报