HDU 1024 DP

题意 : 这个题目就是问你你一串数字分成 m 段连续和 问你 最大的划分是怎样的 输出这个划分和。

题解 : 如果不计时间复杂度 和 空间复杂度的话我们不难设计出一个动态规划的方程就是

     dp (i,j,k) 表示前 i 个分成 j 段 k 取 0 / 1 表示第i个数选没选 
     那么转移的方程为
     dp (i,j,0) = max (dp(i - 1,j,0),dp[i - 1,j,1));
     dp (i,j,1) = max (dp(i - 1,j - 1,0),dp (i - 1,j - 1,1)) + a (i);

可惜这么做会爆内存,所以我门不难想到滚动数组,然后就写一个滚动数组就好了
别忘记边界
dp (0,0) = 0;

这样就可以ac 这个题了
吐槽一下 : 这个题没给m 的范围 emmm……..

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
#define ll long long
using namespace std;
const int INF = 1e9 + 7;
const int maxn = 1e6 + 10;
int n,m;
ll dp[1005][2] = {0};
ll a[maxn] = {0};
int main () {
    while (scanf ("%d%d",&m,&n) != EOF) {
        for (int i = 1;i <= n; ++ i) {
            scanf ("%lld",&a[i]);
        }
        for (int i = 0;i <= m; ++ i) dp[i][0] = dp[i][1] = -INF;
        dp[0][0] = 0;
        for (int i = 1;i <= n; ++ i) {
            int lim = min (i,m);
            for (int j = 1;j <= lim; ++ j) {
                dp[j][0] = max (dp[j][1],dp[j][0]);
                dp[j][1] = max (dp[j][1],dp[j - 1][0]) + a[i];
            }
        }
        printf ("%lld\n",max (dp[m][1],dp[m][0]));
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值