• HDU 1244 Max Sum Plus Plus Plus


    传送门

    题目大意:

    给一个序列,要求将序列分成m段,从左至右每一段分别长l1,l2,...lm,求最大的和是多少。

    题目分析:

    和最大m段子段和相似,先枚举(i in [1,m]),然后$j in [num[m], n] $,dp转移为: $$dp[j][i] = max(dp[j - 1][i], dp[j - num[i]][i - 1] + sum[j] - sum[i - num[i]])$$

    code:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<string>
    //#include<vector>
    using namespace std;
    
    const int N = 1005, M = 25;
    int n, m, num[N];
    typedef long long ll;
    ll sum[N], f[N][N];
    
    inline int read(){
        ll i = 0, f = 1; char ch = getchar();
        for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
        if(ch == '-') f = -1, ch = getchar();
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            i = (i << 3) + (i << 1) + (ch - '0');
        return i * f;
    }
    
    inline void wr(ll x){
        if(x < 0) putchar('-'), x = -x;
        if(x > 9) wr(x / 10);
        putchar(x % 10 + '0');
    }
    
    int main(){
        while(n = read()){
            m = read();
            sum[0] = 0;
            for(int i = 1; i <= m; i++) num[i] = read();
            for(int i = 1; i <= n; i++){
                ll x = read() * 1LL;
                sum[i] = sum[i - 1] + x;
            }
            int now = 0;
            for(int i = 1; i <= m; i++){
                now += num[i];
                for(int j = now; j <= n; j++)
                    f[j][i] = max(f[j - 1][i], f[j - num[i]][i - 1] + sum[j] - sum[j - num[i]]);
            }
            wr(f[n][m]), putchar('
    ');
        }
    }
    
  • 相关阅读:
    libev & libevent简介
    MyEclipse10+Flash Builder4+BlazeDS+Tomcat7配置J2EE Web项目报错(一)
    增加表空间大小的四种方法
    JavaScript获取某年某月的最后一天
    Not in 改写左连接不需要关注连接列是否重复数据
    自连接
    左链接,右连接
    In,内链接和空值
    HighCharts基本折线图
    NetBeans运行项目报错
  • 原文地址:https://www.cnblogs.com/CzYoL/p/7659206.html
Copyright © 2020-2023  润新知