P3009 [USACO11JAN] Profits S 题解复盘

P3009 USACO11JAN Profits S 题解复盘

模块:线性 DP

目标:求连续子数组的最大和(最大子段和)

基本信息

项目 内容
题目编号、来源 P3009 洛谷 / USACO11JAN Profits
训练层级 A 模板题
知识版块 线性 DP、最大子段和

解题前 · 关键信号识别

维度 分析
目标、约束、底层结构 目标 :求一个连续区间,使区间和最大。 约束 :必须是连续区间。 底层结构:当前位置的最优答案只依赖于前一个位置,因此属于线性 DP。
数据规模 N≤10^5,必须使用 O(n) 算法。
候选算法和依据 算法:线性 DP(最大子段和)。 依据:当前位置只有两种选择:重新开始一个新区间,或者接到前面的连续区间后面。
复杂度预判 时间复杂度 O(n),空间复杂度 O(n)(可优化为 O(1))。

解题后 · 外化复盘

维度 内容
实现结构 / 核心思路 定义 dp[i] 表示以第 i 个数结尾 的最大连续子段和。当前位置可以重新开始,也可以接在前面的连续区间之后,因此:dp[i]=max(v[i],dp[i-1]+v[i])。最后遍历 dp 取最大值即可。
错因回溯 1. 一开始误认为是区间 DP,实际上与区间合并没有关系。 2. ans 初始化成 0,导致全负数数据出错。 3. 没有意识到状态必须是"以 i 结尾",而不是任意区间。
边界和易错点 1. dp[1]=v[1]。 2. ans 初始化为 dp[1] 或一个极小值。 3. 全负数时答案仍然是最大的那个负数,而不是 0
下次看到什么信号,我应该想到这个方法 看到"连续区间""最大和""最大利润""最大收益",立即想到:最大子段和(Kadane)+ 线性 DP。

AC 完整代码

cpp 复制代码
#include<iostream>
#include<algorithm>
using namespace std;

int dp[100005];

int main()
{
    int n;
    cin>>n;

    int v[100005];

    for(int i=1;i<=n;i++)
        cin>>v[i];

    dp[1]=v[1];
    int ans=dp[1];

    for(int i=2;i<=n;i++)
    {
        dp[i]=max(dp[i-1]+v[i],v[i]);
        ans=max(ans,dp[i]);
    }

    cout<<ans;

    return 0;
}

本题知识点总结

1. 状态定义

cpp 复制代码
dp[i]

表示:

以第 i 个元素结尾的最大连续子段和。


2. 状态转移

当前位置有两种选择:

重新开始:

cpp 复制代码
v[i]

或者:

接到前面的连续区间:

cpp 复制代码
dp[i-1]+v[i]

所以:

cpp 复制代码
dp[i]=max(v[i],dp[i-1]+v[i]);

3. 为什么必须是"以 i 结尾"?

因为只有这样:

下一状态:

cpp 复制代码
dp[i+1]

才能直接利用:

cpp 复制代码
dp[i]

如果状态定义成:

text 复制代码
前 i 个数中的最大子段和

就无法完成转移。


4. 为什么不是区间 DP?

区间 DP 一般具有:

text 复制代码
区间合并

例如:

cpp 复制代码
dp[l][r]

而最大子段和:

每个状态只依赖:

cpp 复制代码
dp[i-1]

属于:

text 复制代码
线性 DP

5. 空间优化

由于:

cpp 复制代码
dp[i]

只依赖:

cpp 复制代码
dp[i-1]

因此可以压缩成:

cpp 复制代码
int cur=v[1];

空间优化到:

text 复制代码
O(1)

一句话总结

看到"连续区间最大和",立即想到:dp[i] 表示以第 i 个元素结尾的最大连续子段和,转移:dp[i]=max(v[i],dp[i-1]+v[i])

相关推荐
tudousisi2221 小时前
P2800 又上锁妖塔 题解复盘
动态规划
evans在进步21 小时前
LeetCode 322:零钱兑换——Java 动态规划详解
java·leetcode·动态规划
我变成萤火虫1 天前
2026 ICPC沈阳邀请赛Vp补题
数据结构·c++·算法·贪心算法·stl·排序算法·动态规划
wangjialelele2 天前
动态规划DP经典题型总结(Java、C++):路径、子数组、子序列、背包问题详解
java·c++·算法·面试·动态规划·代理模式
evans在进步2 天前
LeetCode 198:打家劫舍——Java 动态规划详解
java·leetcode·动态规划
(❁´◡`❁)Jimmy(❁´◡`❁)3 天前
P1156 [USACO01OPEN] 垃圾陷阱
算法·动态规划
OuO-23 天前
笔试强训 Day 44:最小差值、kotori 和素因子、dd 爱科学 1.0
二分查找·动态规划·贪心·模拟·记忆化搜索·递归·状态表示优化
银-豆豆4 天前
数据结构与算法-动态规划、回溯与贪心
算法·动态规划
2601_960906724 天前
具备抗弯耐磨的性能特点
大数据·人工智能·物联网·决策树·动态规划