Codeforces 229D Towers

题意:城市中有从左到右排列起来的高度为hi的n个塔。现在要求作出一些改变使得景观更美丽,也就是要从左到右排列起来的塔呈非递减序列。你可以用吊车吊起一座塔然后叠加到左右相邻的任意一座塔上,这样新塔的高度等于两座塔之和,每次做这样的操作,塔的总数都会减少1(废话)。问最少进行几次这样子的操作可以使得景观美丽。

dp(i)表示使得前i个塔美丽的最小操作次数,sum(i)表示前i座塔的前缀和,last(i)表示使得前i个塔美丽操作次数最小的情况下,最右侧一座塔最小的塔高。

那么就有状态转移方程:dp(i)=min{dp(j)+i-j+1},sum(i)-sum(j)>=last(j).

 1 #include <cstdio>
 2 int dp[5010],sum[5010],last[5010];
 3 int main()
 4 {
 5     int n;
 6     scanf("%d",&n);
 7     for(int i = 1;i <= n;i++){
 8         int a;
 9         scanf("%d",&a);
10         sum[i] = sum[i-1]+a;
11         dp[i] = last[i] = 1<<30;
12     }
13     for(int i = 1;i <= n;i++){
14         for(int j = 0;j < i;j++){
15             if(sum[i]-sum[j] >= last[j] && dp[i] >= dp[j]+i-j-1){
16                 dp[i] = dp[j]+i-j-1;
17                 if(last[i] > sum[i]-sum[j]) last[i] = sum[i]-sum[j];
18             }
19         }
20     }
21     printf("%d
",dp[n]);
22     return 0;
23 }
View Code
原文地址:https://www.cnblogs.com/zhexipinnong/p/3433333.html