zoukankan      html  css  js  c++  java
  • Codeforces 229D Towers

    http://codeforces.com/problemset/problem/229/D

    题意:有n(1<=n<=5,000)座塔排在一条直线上,从左到右每个塔的高度分别为hi(1<=hi<=100,000),每次操作你可以选择一座塔(假设是第i座),用吊车把它吊起来,然后放到与它相邻的一座塔上(可以是第i-1座也可以是第i+1座),这样,新塔的高度为两座塔的和,完成操作后,塔的总数减少一座。问最少需要多少次操作可以使得所有的塔从左到右形成一个非递减序列。

    思路:

    我们可以这样设计dp:f[i][j]=min(f[j-1][k]+i-j-1)这是n^3的转移

    我们发现如果以某个位置为末尾,那么一定是当前"块"里面"块"的高度最小的时候就是最优解,所以我们的转移从n^2变成了n   

    而枚举状态的效率是O(n),总的就是O(n^2)

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<iostream>
     6 int n,a[200005],sum[200005];
     7 int mn[200005],pd[200005],num[200005];
     8 int read(){
     9     int t=0,f=1;char ch=getchar();
    10     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    11     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
    12     return t*f;
    13 }
    14 int main(){
    15     n=read();
    16     for (int i=1;i<=n;i++) a[i]=read();
    17     for (int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
    18     for (int i=1;i<=n;i++){
    19         if (i==1){
    20             mn[1]=0;
    21             num[1]=a[1];
    22             continue;
    23         }
    24         bool flag=0;mn[i]=0x3f3f3f3f;
    25         for (int j=i;j>=1;j--){
    26            if (num[j-1]<=sum[i]-sum[j-1]&&mn[i]>mn[j-1]+i-j){
    27                 mn[i]=mn[j-1]+i-j;
    28                 flag=1;
    29                 num[i]=sum[i]-sum[j-1];
    30            }    
    31         }
    32         if (flag) continue;
    33         mn[i]=i-1;
    34         num[i]=sum[i];
    35     }
    36     return 0;
    37 }
  • 相关阅读:
    flex 图表使用百分比示例
    flex 图标设置百分比或者其它符号
    大学生求职(打油诗一首)
    flex 图表categoryField设置 labelFunction使用
    如何配置EclipseMe
    google chart图表使用
    Codeforces #Round 632 div2 A~C
    牛客的两道dfs
    约数
    Atcoder ABC162 D RGB Triplets
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5621599.html
Copyright © 2011-2022 走看看