codeforces 448C C. Painting Fence(分治+dp)
2015-09-16 13:19
561 查看
题目链接:
codeforces 448C题目大意:
给出n个杆子,每个杆子有一个长度,每次可以刷一行或一列,问最少刷多少次可以将整个墙刷成***。题目分析:
首先我们能够想到,如果横着刷,为了得到最优解,当前刷的位置的下面也必须横着刷,然后对于每种情况都可以通过n次竖着刷得到整个***的墙。所以我们采取分治的策略进行动态规划,也就是对于每个状态划分为两种情况讨论,如果要刷横向的话,最矮要刷到最矮的柱子的高度才可能得到比竖着刷优的解,然后就变成了多个具有相同性质的规模更小的墙,然后我们可以采取同样的策略进行分治,知道墙只有一根柱子的时候,可以直接通过一次竖着刷得到最优解,每次判断决策时采取先横着刷和直接竖着刷两种方案中较小的方案。
AC代码:
#include <iostream> #include <cstdio> #include <algorithm> #define MAX 5007 using namespace std; typedef long long LL; int n; LL a[MAX]; LL dp[MAX][MAX]; void solve ( int l , int r , LL h ) { dp[l][r] = r-l+1; if ( l == r ) return; LL hh = 1LL<<48; for ( int i = l ; i <= r ; i++ ) hh = min ( hh , a[i] ); LL ans = hh-h; for ( int i = l ; i <= r ; i++ ) { if ( a[i] == hh ) continue; int j; for ( j = i; j <= r ; j++ ) { if ( j == r ) break; if ( a[j+1] == hh ) break; } solve ( i , j , hh ); ans += dp[i][j]; i = j+1; } dp[l][r] = min ( dp[l][r] , ans ); } int main ( ) { while ( ~scanf ( "%d" , &n )) { for ( int i = 1 ; i <= n ; i++ ) scanf ( "%I64d" , &a[i] ); solve ( 1 , n , 0 ); printf ( "%I64d\n" , dp[1] ); } }
相关文章推荐
- 【ionic&AngularJS】用户头像压缩上传,按比例缩小。
- jQuery前端验证多种方式
- LeetCode_OJ【19】Remove Nth Node From End of List
- jQuery提交JSON文件至php网页,保存为文档文件
- jsp语法总结
- 对 Jsp及Servlet 的简单剖析
- jsp九大内置对象和四个作用域
- JSTL 核心标签库 使用
- javascript DOM编程艺术笔记——CH9 CSS-DOM
- html_1基础
- jsp中session的生命周期
- javascript DOM编程艺术笔记——CH8 Enhancing content
- JSP四种范围对象的作用域
- jsp的九大内置对象和四大作用域(方法)
- jQuery实现两款有动画功能的导航菜单代码
- javascript中的previousSibling和nextSibling的正确用法
- 关于JavaScript中的事件代理(例子:ul中无数的li上添加点击事件)
- Jquery揭秘系列:谈谈bind,one,live,delegate,on事件及实现
- jquery.tmpl.js 字符串不转码,像Razor里面的@html.Raw()一样输出
- React Native for Android初探