当前位置:首页 > 洛谷 > 洛谷1220题解:动态规划与区间DP优化解法(附代码注释)

洛谷1220题解:动态规划与区间DP优化解法(附代码注释)

8个月前 (06-26)

洛谷1220题解:动态规划与区间DP优化解法(附代码注释) 洛谷 动态规划 区间DP 前缀和 C++ 第1张

一、题目解读

洛谷1220题要求计算在n个位置放置灯的情况下,通过关闭连续区间灯并移动至区间端点,使得总耗电量最小。需考虑灯的功率与位置差异,设计高效的算法求解最优策略。

二、解题思路

1. 动态规划 + 区间DP:定义状态dp[i][j][0/1]表示关闭i-j区间灯后,最后位于左端(i)或右端(j)的最小耗电量。

2. 前缀和优化:使用sum数组存储灯功率前缀和,简化区间电量计算。

3. 状态转移核心:

○ 向左扩展:从i+1到i,计算移动至左端的耗电量(考虑剩余区间电量与移动距离)。

○ 向右扩展:从j-1到j,同理计算右端移动耗电。

4. 边界初始化:初始状态为单灯区间dp[c][c][0/1]=0,逐步扩展至全局最优解。

三、解题步骤

1. 输入与预处理:读取n、c及灯位置/功率,计算前缀和sum[]。

2. 初始化dp数组:全部设为无穷大,避免非法状态干扰。

3. 枚举区间长度:从2到n遍历,确保覆盖所有连续区间。

4. 状态转移循环:

○ 计算左扩展成本:dp[i][j][0] = min(从i+1扩展左移成本, 从i+1扩展右移后左移成本)。

○ 计算右扩展成本:dp[i][j][1] = min(从j-1扩展右移成本, 从j-1扩展左移后右移成本)。

5. 输出结果:比较最终区间[1,n]的左右端点耗电最小值。

四、代码与注释

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int MAXN = 55;
int n, c;
int pos[MAXN], power[MAXN];
int sum[MAXN]; // 前缀和数组
int dp[MAXN][MAXN][2]; // dp[i][j][0/1]表示关闭i-j区间的灯,最后位于左/右端的最小耗电量

int main() {
    cin >> n >> c;
    for(int i = 1; i <= n; ++i) {
        cin >> pos[i] >> power[i];
        sum[i] = sum[i-1] + power[i]; // 计算前缀和
    }
    
    memset(dp, 0x3f, sizeof(dp)); // 初始化无穷大
    dp[c][c][0] = dp[c][c][1] = 0; // 起点状态
    
    for(int len = 2; len <= n; ++len) { // 枚举区间长度
        for(int i = 1; i + len - 1 <= n; ++i) { // 枚举左端点
            int j = i + len - 1; // 右端点
        
            // 情况1:从i+1走到i(向左扩展)
            int cost_left = (sum[n] - sum[j] + sum[i]) * (pos[i+1] - pos[i]);
            dp[i][j][0] = min(dp[i+1][j][0] + cost_left, 
                             dp[i+1][j][1] + (sum[n] - sum[j] + sum[i]) * (pos[j] - pos[i]));
            
            // 情况2:从j-1走到j(向右扩展) 
            int cost_right = (sum[n] - sum[j-1] + sum[i-1]) * (pos[j] - pos[j-1]);
            dp[i][j][1] = min(dp[i][j-1][1] + cost_right,
                             dp[i][j-1][0] + (sum[n] - sum[j-1] + sum[i-1]) * (pos[j] - pos[i]));
        }
    }
    
    cout << min(dp[1][n][0], dp[1][n][1]) << endl;
    return 0;
}

五、总结

洛谷1220通过区间DP与动态规划的结合,将复杂的多决策问题转化为可递推状态转移方程。前缀和的应用显著降低了计算复杂度,而分情况讨论移动方向(左/右)的耗电优化,是解题的核心技巧。此解法不仅适用于本题,也为类似区间优化问题提供了通用思路。


原创内容 转载请注明出处

分享给朋友:

相关文章

征服力扣704题:三步掌握经典二分查找算法

征服力扣704题:三步掌握经典二分查找算法

题目重解我们面对的是算法领域最经典的二分查找问题:在一个已排序的整数数组中,快速定位目标值的位置。就像在一本按字母顺序排列的字典中查找单词,我们不需要逐页翻阅,而是通过不断折半的方式快速缩小搜索范围,...

力扣第654题:最大二叉树解题教程 用数组构造最大二叉树

力扣第654题:最大二叉树解题教程 用数组构造最大二叉树

题目解读给定一个不含重复元素的整数数组,我们需要构建一棵最大二叉树。构建规则是:数组中的最大值作为根节点,其左侧子数组构建左子树,右侧子数组构建右子树,然后递归地应用这个规则。这种构建方式体现了分治思...

力扣94:递归之美 轻松掌握二叉树中序遍历

力扣94:递归之美 轻松掌握二叉树中序遍历

题目解读二叉树的中序遍历是一种基础且重要的树遍历方式,其遍历顺序为:先递归地中序遍历左子树,然后访问根节点,最后递归地中序遍历右子树。对于二叉搜索树,中序遍历的结果恰好是节点值的升序排列。给定一个二叉...

从零到一掌握背包问题:洛谷P1164题解精讲,附带优化

从零到一掌握背包问题:洛谷P1164题解精讲,附带优化

题目重解:小A带着m元钱来到餐馆,菜单上有n道菜,每道菜都有确定的价格。现在需要计算出刚好花完m元的点菜方案总数。这个问题看似简单,但当菜品数量增多时,暴力枚举就会变得不可行,需要更高效的算法来解决。...

牛客12576题解题全解析:动态规划+质因数分解实现跳跃问题最优解

牛客12576题解题全解析:动态规划+质因数分解实现跳跃问题最优解

一、题目解读牛客12576题是一道经典的算法题,要求给定起点N和终点M,求解从N到M的最少跳跃次数。题目考察的核心在于路径优化与动态规划思想,需结合数论中的质因数分解技巧,通过合理设计算法降低时间复杂...

洛谷P4551题解题报告:图论与Trie树优化异或路径问题的实战解析

洛谷P4551题解题报告:图论与Trie树优化异或路径问题的实战解析

一、题目解读洛谷P4551题要求在一个无向图中,寻找任意两点路径权值异或后的最大值。题目输入为图的边信息(点数n和n-1条边),每条边包含起点、终点及权值。需输出所有路径中权值异或的最大值。问题核心在...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。