一、 问题描述
二、算法思想
可以使用动态规划来解决这个问题。
首先将数字串拆分为多个数字,用一个数组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 numbers
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= M; j++) {
dp[i][j] = INT_MAX;
}
}
// Base case: no splits
dp[0][0] = 0;
// Dynamic programming to calculate minimum sum
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= M; j++) { // j can be 0 as well
if (j == 0) {
dp[i][j] = getNumber(str, 0, i-1);
} else {
for (int k = 1; k < i; k++) { // k starts from 1
if (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 splits
int 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;
}
执行结果
结语
欲望以提升热忱
毅力以磨平高山
!!!