#DP35. 最少加号

最少加号

GESP C++ 6级模拟题

题目名称:最少加号

知识点

  • 动态规划/搜索算法
  • 字符串处理
  • 数学运算
  • 算法思维

题目描述

给定一个数字字符串,通过在字符串中插入最少的加号,使得表达式的计算结果等于目标数字。

规则说明:

  • 每次"加法"操作是在字符串中插入一个加号
  • 插入所有加号后,表达式按标准算术加法计算
  • 前导零不影响数字的值(例如"03"被视为3)

示例:

  1. 字符串"12":

    • 插入0个加号:结果为12
    • 插入1个加号(如"1+2"):结果为3
    • 因此,要达到目标数字3,最少需要插入1个加号
  2. 字符串"303",目标数字6:

    • 最优方法:"3+03",计算结果为3+3=6
    • 注意:"3+0+3"不是最优方法
    • 因为前导零不影响数字值,"03"被视为3

输入格式

第一行,包含一个字符串 s(1 ≤ len(s) ≤ 40)

第二行,包含一个整数 n(1 ≤ n ≤ 10^5)

输出格式

一行,输出一个整数,表示最少需要插入多少个加号才能使表达式结果等于 n

如果无法通过插入加号使表达式结果等于 n,输出 -1


样例输入1

99999
45

样例输出1

4

样例1说明: 插入4个加号:"9+9+9+9+9" = 45 因此最少需要4个加号


样例输入2

12
3

样例输出2

1

样例2说明: 插入1个加号:"1+2" = 3


样例输入3

303
6

样例输出3

1

样例3说明: 插入1个加号:"3+03" = 3+3 = 6 注意:"03"被视为3,不是"3+0+3"(需要2个加号)


样例输入4

123
6

样例输出4

2

样例4说明: 插入2个加号:"1+2+3" = 6


样例输入5

100
1

样例输出5

-1

提示

  1. 算法思路

    • 这是一个动态规划问题
    • 可以用DP[i][j]表示前i个字符,能否组成和为j
    • 或者使用记忆化搜索
  2. 关键点

    • 前导零的处理:"03"被视为3,"00"被视为0
    • 需要找到最少的加号数量
    • 如果无法达到目标,返回-1
  3. 实现步骤

    • 枚举所有可能的分割方式
    • 对于每种分割,计算表达式的值
    • 找到达到目标值的最少加号数
  4. 优化思路

    • 使用动态规划避免重复计算
    • 状态:dp[i][sum] = 前i个字符,能否组成和为sum,最少需要多少个加号

考察知识点总结

  • ✅ 动态规划/记忆化搜索
  • ✅ 字符串处理
  • ✅ 数学运算
  • 算法思维(状态设计、转移方程)

难度评估

难度: ⭐⭐⭐⭐⭐(较难)

适合: GESP C++ 6级考生练习


数据规模

  • 字符串长度:1 ≤ len(s) ≤ 40
  • 目标数字:1 ≤ n ≤ 10^5

大数据测试建议:

  • len(s) = 40(最大长度)
  • n = 10^5(最大值)
  • 各种边界情况