zoukankan      html  css  js  c++  java
  • HDU 1244 DP

    题目大意:

    我们需要将一串数字分成多个确定个数的连续段,在得到所有段的和的最大值

    定义一个dp[i][j]数组表示在前j个数中取满 i 个段所能得到的最大值

    那么也就是说明在这道题目当中每一段都是必须要被取到的

    能够取到的前提是 j >= cnt[i] //表示前 i 段的数字个数总和

    sum[i] 表示前 i 个数字之和

    我们可以分成两种情况,一种是第i段取到以j号数字结尾

    得到dp[i-1][j-l[i]] + sum[j] - sum[j-l[i]]

    第二种是不以j号数字结尾

    得到dp[i][j-1]

    我们每次在其中取最大值就好了

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    const int INF = 200000000;
    const int M = 22;
    const int N = 1005;
    
    int dp[M][N] , l[M] , a[N] , cnt[M] , sum[N];
    
    int main()
    {
        int m , n;
        while(scanf("%d" , &n) , n){
            scanf("%d" , &m);
            for(int i = 1 ; i<=m ; i++){
                scanf("%d" , l+i);
                cnt[i] = cnt[i-1] + l[i];
            }
            for(int i = 1 ; i<= n ; i++){
                scanf("%d" , a+i);
                sum[i] = sum[i-1] + a[i];
            }
    
            memset(dp , 0 , sizeof(dp));
            /*
            第一次用这个交为了防止结果允许为负数的情况,可以AC
            但是只是简单的dp初始为0,也没问题,个人感觉题目不是出的很严格
            for(int i = 1 ; i<= m ; i++)
                for(int j = cnt[i] ; j<=n ; j++)
                    dp[i][j] = -INF;
            */
            for(int i = 1 ; i<= m ; i++)
                for(int j = cnt[i] ; j<=n ; j++){
                    dp[i][j] = max(dp[i-1][j-l[i]] + sum[j] - sum[j-l[i]] , dp[i][j-1]);
                }
            printf("%d
    " , dp[m][n]);
        }
        return 0;
    }
  • 相关阅读:
    为初次使用linux设置 root密码
    linux如何改为汉化环境
    Linux 标准目录结构
    常用linux terminal 命令
    jquery 获取及设置input各种类型的值
    使用$.getJSON实现跨域ajax请求
    react 异步取数据
    PHP 全局变量
    PHP保存本地日志文件
    全端开发——css(选择器)
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4184591.html
Copyright © 2011-2022 走看看