zoukankan      html  css  js  c++  java
  • luogu P2300 合并韩雨辰神犇

    月光林地传送门

    一道简单dp....(不知道是什么dp)

    状态很简单,但要分为三个数组表示:

    dp[i]表示区间1——i至少合并的次数

    sum[i]表示前缀和

    last[i]表示第i个数

    显然要从左边开始推,当右边加入一个新数时,在保留前j个数不变并合并合法的条件是sum[i]-sum[j]>=last[j]

    想想看,如果后加入的数与前面数的差比前面最后一个数小,那么后加入的数不可能大于等于前面的最后一个数。

    因此,每次扫一遍前面的数,满足条件后保留j值停止,f[i]=f[j]+i-j-1(显然)

    #include<cstdio>
    using namespace std;
    #define ll long long
    #define maxn 200010
    
    ll a[maxn],s[maxn];
    ll f[maxn],last[maxn];
    
    int main() 
    {
        long long  n;
        scanf("%lld",&n);
        for(int i = 1; i <= n; i++)
        {
            scanf("%lld",&a[i]);
            s[i] = s[i - 1] + a[i];
        }
        for(long long i = 1; i <= n; i++) 
        {
            long long j;
            for(j = i - 1; j >= 0; j--)
                if(s[i] - s[j] >= last[i])
                    break;
            f[i] = f[j] + i - j - 1;
            last[i] = s[i] - s[j];
        }
        printf("%lld",f[n]);
        return 0;
    }

     

  • 相关阅读:
    go基础_defer
    go基础_函数
    go基础_控制语句
    go基础_数组
    go基础_切片
    go命令行参数
    Hdu2795Billboard线段树
    Hdu1394Minimum Inversion Number线段树
    Hdu1754单点更新
    Hdu1166单点更新线段树
  • 原文地址:https://www.cnblogs.com/charlesss/p/10346937.html
Copyright © 2011-2022 走看看