codeforces 448C Painting Fence
2016-03-01 20:27
316 查看
C. Painting Fence
time limit per test
1 second
memory limit per test
512 megabytes
input
standard input
output
standard output
Bizon the Champion isn't just attentive, he also is very hardworking.
Bizon the Champion decided to paint his old fence his favorite color, orange. The fence is represented as n vertical planks, put in a row. Adjacent planks have no gap between
them. The planks are numbered from the left to the right starting from one, the i-th plank has the width of 1 meter and the height of ai meters.
Bizon the Champion bought a brush in the shop, the brush's width is 1 meter. He can make vertical and horizontal strokes with the brush. During a stroke the brush's full
surface must touch the fence at all the time (see the samples for the better understanding). What minimum number of strokes should Bizon the Champion do to fully paint the fence? Note that you are allowed to paint the same area of the fence multiple times.
Input
The first line contains integer n (1 ≤ n ≤ 5000) — the number of fence planks. The second line contains n space-separated
integersa1, a2, ..., an (1 ≤ ai ≤ 109).
Output
Print a single integer — the minimum number of strokes needed to paint the whole fence.
Examples
input
output
input
output
input
output
Note
In the first sample you need to paint the fence in three strokes with the brush: the first stroke goes on height 1 horizontally along all the planks. The second stroke goes on height 2 horizontally and
paints the first and second planks and the third stroke (it can be horizontal and vertical) finishes painting the fourth plank.
In the second sample you can paint the fence with two strokes, either two horizontal or two vertical strokes.
In the third sample there is only one plank that can be painted using a single vertical stroke.
*****************************************************************************************************************************
solution:cf上的很多题都有其特殊的“特性”,把握住特性就能很好地解决问题。比如这个问题中,我们要把握住两点:一,一次涂漆尽可能多涂(ps:这不是废话吗);二,就是一行如果水平涂满了,那这行下面的所有行都是水平涂满的,这是为什么呢?简单证明一下:如果下面那些行中有些是竖涂的,那么请你想想,它为什么不涂到一列的顶呢?否则不是浪费了吗?
所以,我们可以得出,对下标为l--r的一段墙,我们有两种策略,一种是全部竖涂(参考前面的,想想为什么),另一种是横涂到这段墙的最小值(把l--r全部能涂的行从底下开始都涂了),再把这段分成几个小段累加(你也许会问,怎么不全部横涂呢?这是因为受到高度的限制,所以必须根据最小高度分成几段分别处理),每次返回两种策略的最小值,用分治来实现。
找最小值可以用线段树来优化。
time limit per test
1 second
memory limit per test
512 megabytes
input
standard input
output
standard output
Bizon the Champion isn't just attentive, he also is very hardworking.
Bizon the Champion decided to paint his old fence his favorite color, orange. The fence is represented as n vertical planks, put in a row. Adjacent planks have no gap between
them. The planks are numbered from the left to the right starting from one, the i-th plank has the width of 1 meter and the height of ai meters.
Bizon the Champion bought a brush in the shop, the brush's width is 1 meter. He can make vertical and horizontal strokes with the brush. During a stroke the brush's full
surface must touch the fence at all the time (see the samples for the better understanding). What minimum number of strokes should Bizon the Champion do to fully paint the fence? Note that you are allowed to paint the same area of the fence multiple times.
Input
The first line contains integer n (1 ≤ n ≤ 5000) — the number of fence planks. The second line contains n space-separated
integersa1, a2, ..., an (1 ≤ ai ≤ 109).
Output
Print a single integer — the minimum number of strokes needed to paint the whole fence.
Examples
input
5 2 2 1 2 1
output
3
input
2 2 2
output
2
input
1 5
output
1
Note
In the first sample you need to paint the fence in three strokes with the brush: the first stroke goes on height 1 horizontally along all the planks. The second stroke goes on height 2 horizontally and
paints the first and second planks and the third stroke (it can be horizontal and vertical) finishes painting the fourth plank.
In the second sample you can paint the fence with two strokes, either two horizontal or two vertical strokes.
In the third sample there is only one plank that can be painted using a single vertical stroke.
*****************************************************************************************************************************
solution:cf上的很多题都有其特殊的“特性”,把握住特性就能很好地解决问题。比如这个问题中,我们要把握住两点:一,一次涂漆尽可能多涂(ps:这不是废话吗);二,就是一行如果水平涂满了,那这行下面的所有行都是水平涂满的,这是为什么呢?简单证明一下:如果下面那些行中有些是竖涂的,那么请你想想,它为什么不涂到一列的顶呢?否则不是浪费了吗?
所以,我们可以得出,对下标为l--r的一段墙,我们有两种策略,一种是全部竖涂(参考前面的,想想为什么),另一种是横涂到这段墙的最小值(把l--r全部能涂的行从底下开始都涂了),再把这段分成几个小段累加(你也许会问,怎么不全部横涂呢?这是因为受到高度的限制,所以必须根据最小高度分成几段分别处理),每次返回两种策略的最小值,用分治来实现。
找最小值可以用线段树来优化。
#include<cstdio>
#include<iostream>
#define p1 id<<1#define p2 (id<<1)+1using namespace std;
int a[100005],tree[450000];
int n,ans;
void build(int id,int l,int r)
{
if(l==r)
{
tree[id]=a[l];
return;
}
int mid=(l+r)/2;
build(p1,l,mid);
build(p2,mid+1,r);
tree[id]=min(tree[p1],tree[p2]);
}
int lookup(int id,int l,int r,int x,int y)
{
if(l>y||r<x) return -1;
if(x<=l&&r<=y) return tree[id];
int mid=(l+r)/2;
int s1=lookup(p1,l,mid,x,y);
int s2=lookup(p2,mid+1,r,x,y);
if(s1==-1) return s2;
if(s2==-1) return s1;
return min(s1,s2);
}
int dfs(int l,int r,int under)
{
if(l>r) return 0;
int mint=lookup(1,1,n,l,r);
int s1,s2,k;
s1=r-l+1;
s2=mint-under;
k=l;
for(int i=l;i<=r;i++)
if(a[i]==mint)
{
s2=s2+dfs(k,i-1,mint);
k=i+1;
}
s2=s2+dfs(k,r,mint);
return min(s1,s2);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,1,n);
ans=min(n,dfs(1,n,0));
cout<<ans<<endl;
return 0;
}
相关文章推荐
- 计算几何 usaco Fencing the Cows 圈奶牛
- javascript中对象总结
- jQuery参考手册
- 结合firebug学习jQuery选择器
- jQuery--选择器详解
- CSS居中的方法总结
- js中智能右键菜单
- CSS布局模型思考
- 两个Jsp网页间登陆页简单后台验证,并且防止未登录用户绕过登陆页
- 移动前端开发之viewport的深入理解
- javascript同源策略
- ExtJS之Progressbar进度条的手动模式和自动模式。
- CheckBox全选,不要相信JQuery,还是原生的好~
- bootstrap3.3 兼容IE8处理方法
- ## 创建第一个node.js工程 ##
- #学习笔记#(47)AngularJS作用域$emit $bordercast
- javascript键值映射
- jQuery--jq对象和dom对象
- magento 提交订单处理js
- 如何使用HTML5+CSS3绘制一个QQ 企鹅Logo