UVa 11683

来源:互联网 发布:去哪里看淘宝图片护盾? 编辑:程序博客网 时间:2024/06/06 02:28

题目:利用激光切割机切削一个矩形的材料,每次只能从上向下切掉1mm后的矩形,

            问切削成如下给出的形状需要切削多少次。

分析:线段树,数据结构。将图形看成是二叉树,从上往下按最高的点分段即可。

            整个切削过程遇到极大值点就会分成两段,就是一个构造二叉树的过程;

            这里不用构造树,利用递归分别计算分段的两个子树即可;

            于是问题就变成了怎么寻找一个区间内的最大值,枚举会超时;

            这里就需要线段树出场了,寻找区间最大值只需要O(lgN); 

说明:这里注意下降的高度可能不是1,需要记录上次高度做差。

#include <stdio.h>int height[10001];typedef struct _segment_tree {_segment_tree * Lchild;_segment_tree * Rchild;int             Lvalue;int             Rvalue;int             Index;}st;st *st_root;st  st_node[20002];int st_node_use_count;st * st_make_tree(int L, int R){st * np = &st_node[st_node_use_count ++];np->Lvalue = L;np->Rvalue = R;np->Index  = 0;if (L < R) {np->Lchild = st_make_tree(L, (L+R)/2);np->Rchild = st_make_tree((L+R)/2+1, R);}else {np->Lchild = NULL;np->Rchild = NULL;}return np;}void st_initial(int L, int R){st_node_use_count = 0;st_root = st_make_tree(L, R);}void st_set_value(st * root, int index){if (!root) {return;}if (!root->Index || height[root->Index] < height[index]) {root->Index = index;}int Mid = (root->Lvalue + root->Rvalue)/2;if (index <= Mid) {st_set_value(root->Lchild, index);}else {st_set_value(root->Rchild, index);}}void st_set_value(int index){st_set_value(st_root, index);}int st_get_max_index(st * root, int L, int R){if (!root) {return 0;}if (root->Lvalue == L && root->Rvalue == R) {return root->Index;}int Mid = (root->Lvalue + root->Rvalue)/2;if (R <= Mid) {return st_get_max_index(root->Lchild, L, R);}else if (L > Mid) {return st_get_max_index(root->Rchild, L, R);}else {int id1 = st_get_max_index(root->Lchild, L, Mid);int id2 = st_get_max_index(root->Rchild, Mid+1, R);return height[id1] >= height[id2] ? id1 : id2;}}int st_get_max_index(int L, int R){return st_get_max_index(st_root, L, R);}int f(int L, int R, int H){if (L > R) {return 0;}int now = st_get_max_index(L, R);return f(L, now-1, height[now]) + f(now+1, R, height[now]) + H-height[now];}int main(){int A, C;while (~scanf("%d",&A) && A) {scanf("%d",&C);for (int i = 1; i <= C; ++ i) {scanf("%d",&height[i]);}st_initial(1, C);for (int i = 1; i <= C; ++ i) {st_set_value(i);}printf("%d\n",f(1, C, A));}return 0;}