【cf229D】Towers
来源:互联网 发布:显示淘宝下架插件 编辑:程序博客网 时间:2024/06/05 02:19
link to problem
【题目大意】
有n(1<=n<=5,000)座塔排在一条直线上,从左到右每个塔的高度分别为hi(1<=hi<=100,000),每次操作你可以选择一座塔(假设是第i座),用吊车把它吊起来,然后放到与它相邻的一座塔上(可以是第i-1座也可以是第i+1座),这样,新塔的高度为两座塔的和,完成操作后,塔的总数减少一座。问最少需要多少次操作可以使得所有的塔从左到右形成一个非递减序列。
【题解】贪心+dp
首先我们可以知道,当 j < i 时必有a[j] <= a[i];
设 s[i]=∑a[j] (1<=j<=i) , 所以如果要合并第 i-j 座塔,必然满足:s[j]-s[i-1]>=a[i-1],此时可以根据贪心思想更新a[i-1];
- 【呆马(⊙o⊙)】
#include <cstdio>#include <iostream>#define inf 1000000000long long n,a[5010],f[5010],s[5010];int main(){ scanf("%I64d\n",&n); for (int i=1;i<=n;++i) scanf("%I64d ",&a[i]); for (int i=1;i<=n;++i) s[i]=a[i]+s[i-1]; for (int i=1;i<=n;++i) a[i]=f[i]=inf; for (int i=1;i<=n;++i) for (int j=0;j<i;++j) if (a[j]<=s[i]-s[j]) { f[i]=std::min(f[i],f[j]+i-j-1); if (a[i]>s[i]-s[j]) a[i]=s[i]-s[j]; } printf("%I64d\n",f[n]); return 0;}
0 0
- 【cf229D】Towers
- Towers
- Towers
- A. Towers
- codeforces229D. Towers
- Twin Towers
- Hanoi Towers
- A. Towers
- The Twin Towers
- 10066 - The Twin Towers
- uva_10066The Twin Towers
- 229D - Towers DP
- 10066 - The Twin Towers
- poj1920 Towers of Hanoi
- BNU The Twin Towers
- UVALive 4050 Hanoi Towers
- UVaOJ_10066 - The Twin Towers
- codeforces Towers 题解
- 剑指offer 44题 【抽象建模能力】扑克牌的顺序
- 通过二叉树的遍历理解递归
- javascript 图片转base64
- 【jzoj4668】【腐败】【数论】【快速乘】
- unity语言本地化插件 I2 Location2.5.6使用简单记录
- 【cf229D】Towers
- JNI - 加解密时错误的使用strlen和strncpy函数
- 对有数据的CUBE加IO
- 一句代码搞定 Android 底部弹框
- 帮助
- java程序员最常犯的错误
- iOS出现按钮文字等的叠加问题
- mapperLocations属性通配符的使用
- HDU 4006 The kth great number