【NOIP2013】积木大赛

原题:

 n<=1e5,h<=1e4

性质:对于一段连续区间(经过一些列操作后仍然连续)的最低点h[i],毫无疑问一定要进行h[i]次操作把下边削平,这一定是最优解

由此·,f(l,r)表示分治区间[l,r],选出最低点然后递归分治

时间并不是n^2而是n*h,因为每次分治至少要削掉一层(我写得代码并不保证这一点,可见数据很弱)

复杂度不很正确,时间紧张,但是就算极端数据应该也可以优化掉

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int n,a[110000];
 5 int f(int x,int y,int z){
 6     if(x>y)  return 0;
 7     int mn=0;  a[0]=1000000007;
 8     for(int i=x;i<=y;++i)if(a[i]<a[mn])  mn=i;
 9     return f(x,mn-1,a[mn])+f(mn+1,y,a[mn])+(a[mn]-z);
10 }
11 int main(){
12     cin>>n;
13     for(int i=1;i<=n;++i)  scanf("%d",&a[i]);
14     cout<<f(1,n,0)<<endl;
15     return 0;
16 }
View Code
原文地址:https://www.cnblogs.com/cdcq/p/12283639.html