【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 }