#DP35. 最少加号
最少加号
GESP C++ 6级模拟题
题目名称:最少加号
知识点
- 动态规划/搜索算法
- 字符串处理
- 数学运算
- 算法思维
题目描述
给定一个数字字符串,通过在字符串中插入最少的加号,使得表达式的计算结果等于目标数字。
规则说明:
- 每次"加法"操作是在字符串中插入一个加号
- 插入所有加号后,表达式按标准算术加法计算
- 前导零不影响数字的值(例如"03"被视为3)
示例:
-
字符串"12":
- 插入0个加号:结果为12
- 插入1个加号(如"1+2"):结果为3
- 因此,要达到目标数字3,最少需要插入1个加号
-
字符串"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
提示
-
算法思路:
- 这是一个动态规划问题
- 可以用DP[i][j]表示前i个字符,能否组成和为j
- 或者使用记忆化搜索
-
关键点:
- 前导零的处理:"03"被视为3,"00"被视为0
- 需要找到最少的加号数量
- 如果无法达到目标,返回-1
-
实现步骤:
- 枚举所有可能的分割方式
- 对于每种分割,计算表达式的值
- 找到达到目标值的最少加号数
-
优化思路:
- 使用动态规划避免重复计算
- 状态:dp[i][sum] = 前i个字符,能否组成和为sum,最少需要多少个加号
考察知识点总结
- ✅ 动态规划/记忆化搜索
- ✅ 字符串处理
- ✅ 数学运算
- ✅ 算法思维(状态设计、转移方程)
难度评估
难度: ⭐⭐⭐⭐⭐(较难)
适合: GESP C++ 6级考生练习
数据规模
- 字符串长度:1 ≤ len(s) ≤ 40
- 目标数字:1 ≤ n ≤ 10^5
大数据测试建议:
- len(s) = 40(最大长度)
- n = 10^5(最大值)
- 各种边界情况