当前位置:首页 > 洛谷 > 洛谷P4999题解析:动态规划求解数字拆分与求和问题(附代码)

洛谷P4999题解析:动态规划求解数字拆分与求和问题(附代码)

5个月前 (06-19)

洛谷P4999题解析:动态规划求解数字拆分与求和问题(附代码)  动态规划 记忆化搜索 数字拆分 大数求和 第1张

一、题目解读

洛谷P4999题要求处理给定区间 [L, R] 内数字的拆分与求和问题。每个数字需拆分为其各位数字之和,并计算区间内所有数字之和的累加结果。题目需考虑大数情况,并采用取模运算(MOD=1e9+7)防止溢出。

二、解题思路

核心思路为动态规划 + 记忆化搜索。通过将数字拆分为位数与各位数字之和的状态,利用递归计算不同位数的数字和,并通过记忆化存储避免重复计算。关键在于设计状态转移方程,处理前缀区间和的累加。

三、解题步骤

1. 预处理数字位数:将输入的大数 L 和 R 逆序存储为 digit 数组,记录每位数字。

2. 定义状态 dp[pos][sum]:表示处理到第 pos 位、当前数字和为 sum 时的方案数。

3. 递归计算与记忆化:

    递归终点为 pos=0,直接返回 sum。

    若当前位未受限(非最高位),且已存在记忆化结果,直接返回。

    枚举 0~up(最高位为 digit[pos],其余位为 9)的每位数字,递归计算下一位,累加结果并取模。

    更新记忆化数组。

4. 区间求和:通过 solve(R) - solve(L-1) 计算答案,并处理负数情况(+MOD 后再取模)。

四、代码及注释

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

const int MOD = 1e9+7; // 取模常量
typedef long long ll; // 定义长整型
ll dp[20][200]; // dp[pos][sum]:处理到第pos位、数字和为sum的方案数
int digit[20]; // 存储数字的逆序位数

// 记忆化搜索函数
ll DFS(int pos, int sum, bool limit) {
    if(pos == 0) return sum; // 递归终点:当前位为0,返回数字和
    if(!limit && dp[pos][sum]!= -1) // 非最高位且已记忆化,直接返回
        return dp[pos][sum];
    
    int up = limit? digit[pos] : 9; // 最高位限制为当前位数,其余位可到9
    ll res = 0;
    for(int i = 0; i <= up; ++i) { // 枚举当前位数字
        // 递归计算下一位,累加结果并取模
        res = (res + dfs(pos-1, sum+i, limit && i==up)) % MOD;
    }
    
    if(!limit) dp[pos][sum] = res; // 非最高位时记忆化存储
    return res;
}

// 主计算函数:将数字拆解为位数,调用dfs
ll solve(ll x) {
    memset(dp, -1, sizeof dp); // 初始化记忆化数组
    int len = 0;
    while(x) { // 逆序存储数字位数
        digit[++len] = x % 10;
        x /= 10;
    }
    return dfs(len, 0, true); // 从最高位开始,限制位数
}

int main() {
    int T;
    cin >> T; // 输入测试组数
    while(T--) {
        ll L, R;
        cin >> L >> R; // 输入区间
        // 计算区间和,处理负数情况
        cout << (solve(R) - solve(L-1) + MOD) % MOD << endl;
    }
    return 0;
}

五、总结

本解法通过动态规划将数字拆分问题转化为状态转移,结合记忆化搜索优化递归效率,有效解决大区间求和问题。时间复杂度为 O(位数×数字和范围),空间复杂度为 O(位数×数字和范围)。在实际应用中,记忆化搜索可显著提升重复计算场景的性能,是算法优化的关键技巧。


参考:动态规划

原创内容 转载请注明出处

分享给朋友:

相关文章

NOIP2005 普及组 洛谷P1408 背包问题的空间优化技巧与实战应用

NOIP2005 普及组 洛谷P1408 背包问题的空间优化技巧与实战应用

题目重解想象你是一名药师,有t分钟在山上采集m种草药。每种草药需要time分钟采集,价值为num。这就像考试时分配时间做题,要选择收益最大的题目组合。题目要求计算在规定时间内能获得的最大草药价值。解题...

IOI 1994 洛谷1216:如何用O(1)空间解决数字三角形问题?附代码实现

IOI 1994 洛谷1216:如何用O(1)空间解决数字三角形问题?附代码实现

题目重解:数字三角形是一个经典的动态规划问题,给定一个由数字组成的三角形结构,从顶部出发,每次可以移动到下方相邻的数字,最终到达底部。我们需要找到一条路径,使得路径上经过的数字总和最大。这个问题可以很...

GESP2023年六级真题解析:动态规划解决小杨买饮料问题(洛谷3873)

GESP2023年六级真题解析:动态规划解决小杨买饮料问题(洛谷3873)

一、题目解读小杨买饮料是GESP 2023年六级认证考试中的一道经典动态规划题目,考察学生对背包问题的理解和应用能力。题目描述小杨需要购买n种饮料,每种饮料有特定的体积w和价格v,他要在不超过容量l的...

NOIP 2008火柴棒等式题解(C++代码实现)  动态规划与枚举算法详解

NOIP 2008火柴棒等式题解(C++代码实现) 动态规划与枚举算法详解

一、题目解读火柴棒等式问题(NOIP 2008,洛谷P1149)要求使用给定数量的火柴棒,构造形如 A + B = C 的等式,其中A、B、C均为整数,且火柴棒总数恰好等于输入值。需统计符合条件的等式...

2024蓝桥杯省赛B组“传送阵”题解(C++代码+图论算法优化)

2024蓝桥杯省赛B组“传送阵”题解(C++代码+图论算法优化)

一、题目解读2024年蓝桥杯省B组“传送阵”题目要求处理一个包含n个节点的图,节点间存在单向传输关系。每个节点i可传送至a[i]指定的节点,形成可能存在的环结构。题目需求解从任意节点出发能到达的最长路...

【蓝桥杯2015省赛解析】生命之树:树形DP解题全攻略(洛谷P8625代码详解)

【蓝桥杯2015省赛解析】生命之树:树形DP解题全攻略(洛谷P8625代码详解)

一、题目解读    “生命之树”是一道经典的树形结构问题,要求计算一棵带权树中,以某个节点为根的最大子树权值和。题目输入为n个节点及边信息,每个节点有权值wi,...

发表评论

访客

看不清,换一张

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