老oj3999孤独一生

孤独一生

Time Limit:10000MS  Memory Limit:165536K
Total Submit:23 Accepted:11 
Case Time Limit:1000MS

Description

 

Input

第一行一个数N。 
第二行N个整数Hi。 

Output

一行一个整数,表示最小的总体力值。 

Sample Input

 

3
1 3 1

 

Sample Output

 

4

 

Hint

对于10%的数据N<=20。 
对于20%的数据N<=100。 
对于50%的数据N<=5000。 
对于100%的数据1<=N<=500000。 

 

设f[i][j]表示第一个集合结尾是i,第二个集合结尾是j,我们考虑到这两个集合没有本质区别,所以假设i>=j

这是O(N2)

设g[i]=f[i][i-1],sum[i]=sum[i-1]+abs(h[i]-h[i-1]),我们就只需要枚举前面的g[j]就行了

转移为g[i]=min{g[j]+sum[i-1]-sum[j]+abs(h[i]-h[j-1)}

答案就是min(g[i]+sum[n]-sum[i])

绝对值就用树状数组去就可以了

code:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #define maxn 500005
 7 #define lowbit(x) ((x)&(-(x)))
 8 #define inf 4557430888798830399LL
 9 using namespace std;
10 typedef long long int64;
11 char ch;
12 int n,tot,h[maxn],pos[maxn];
13 int64 sum[maxn],f[maxn],ans;
14 struct DATA{
15     int val,num;
16 }list[maxn];
17 bool cmp(DATA a,DATA b){return a.val<b.val;}
18 struct bit{
19     int64 val[maxn];
20     void init(){memset(val,63,sizeof(val));}
21     void insert(int x,int64 v){for (;x<=tot;x+=lowbit(x)) val[x]=min(val[x],v);}
22     int64 query(int x){
23         int64 ans=inf;
24         for (;x;x-=lowbit(x)) ans=min(ans,val[x]);
25         return ans;
26     }
27 }T1,T2;
28 bool ok;
29 void read(int &x){
30     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
31     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
32     if (ok) x=-x;
33 }
34 int main(){
35     read(n),n++;
36     for (int i=2;i<=n;i++) read(h[i]);
37     for (int i=1;i<=n;i++) sum[i]=sum[i-1]+abs(h[i]-h[i-1]);
38     for (int i=1;i<=n;i++) list[i]=(DATA){h[i],i};
39     sort(list+1,list+n+1,cmp);
40     pos[1]=tot=1;
41     for (int i=2;i<=n;i++){
42         if (list[i].val!=list[i-1].val) tot++;
43         pos[list[i].num]=tot;    
44     }
45     T1.init(),T2.init();
46     memset(f,63,sizeof(f));
47     f[1]=0,T1.insert(pos[1],f[1]-sum[1]-h[0]),T2.insert(tot-pos[1]+1,f[1]-sum[1]+h[0]);
48     for (int i=2;i<=n;i++){
49         f[i]=sum[i-1]+min(h[i]+T1.query(pos[i]),-h[i]+T2.query(tot-pos[i]));
50         T1.insert(pos[i-1],f[i]-sum[i]-h[i-1]);
51         T2.insert(tot-pos[i-1]+1,f[i]-sum[i]+h[i-1]);
52     }
53     ans=inf;
54     for (int i=1;i<=n;i++) ans=min(ans,f[i]+sum[n]-sum[i]);
55     printf("%I64d\n",ans);
56     return 0;
57 }

 

posted @ 2015-10-30 08:49  chenyushuo  阅读(238)  评论(0编辑  收藏  举报