一、 问题描述
二、算法思想
可以使用动态规划来解决这个问题。
首先将数字串拆分为多个数字,用一个数组nums来存储每个数字。例如,数字串79846会被拆分为数组[7, 9, 8, 4, 6]。
然后定义一个二维数组dp,其中dp[i][j]表示在前i个数字中插入j个加号所能得到的最小值。初始化dp数组为无穷大,除了dp[0][0] = 0。
然后使用两个循环来更新dp数组。外层循环遍历数字串的每个数字,内层循环遍历插入的加号个数。对于每个dp[i][j],可以考虑将数字nums[i]与前面的数字组合成一个新的数,或者将数字nums[i]与前面的数字之间插入加号。取两种情况中的较小值作为dp[i][j]的值。
最后,dp数组的最后一行中的最小值即为所求的最小值。
三、代码实现
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>// Helper function to extract integer value from substring
int getNumber(char* str, int start, int end) {char buffer[12]; // Buffer large enough for max 10 digits + '\0'int length = end - start + 1;strncpy(buffer, str + start, length);buffer[length] = '\0';return atoi(buffer);
}int main() {char str[201];int M;scanf("%s %d", str, &M);int n = strlen(str);int dp[n+1][M+1];// Initialize dp array with large numbersfor (int i = 0; i <= n; i++) {for (int j = 0; j <= M; j++) {dp[i][j] = INT_MAX;}}// Base case: no splitsdp[0][0] = 0;// Dynamic programming to calculate minimum sumfor (int i = 1; i <= n; i++) {for (int j = 0; j <= M; j++) { // j can be 0 as wellif (j == 0) {dp[i][j] = getNumber(str, 0, i-1);} else {for (int k = 1; k < i; k++) { // k starts from 1if (dp[k][j-1] != INT_MAX) {int num = getNumber(str, k, i-1);if (dp[k][j-1] + num < dp[i][j]) {dp[i][j] = dp[k][j-1] + num;}}}}}}// Find the minimum value in dp[n][*] with M splitsint result = INT_MAX;for (int i = 0; i <= M; i++) {if (dp[n][i] < result) {result = dp[n][i];}}printf("%d\n", result);return 0;
}
执行结果
结语
欲望以提升热忱
毅力以磨平高山
!!!