版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mobius_strip/article/details/82915715
题目
将一个数字串拆分成不超过32位有符号整形(2147483647)的数组,求他们的和的最大值。
分析
动态规划(DP)。区间动态规划,按照区间长度更新即可。
预处理:设a(i,j)为从i开始到j结束的数字串的值,如果超过2147483647则为0;
状态定义:f(i,j)为区间[i, j]上的最优解。
转移方程:f(i,j)= max(f(i,k)+ f(k+1,j),a(i,j))
说明
#include <stdio.h> #include <stdlib.h> #include <string.h> long long value[202][202]; long long dp[202][202]; int main() { int N, M, bit[202]; char str[202]; while (~scanf("%d", &N)) while (N --) { scanf("%s", str); M = strlen(str); for (int i = 0; i < M; ++ i) { bit[i+1] = str[i] - '0'; } for (int i = 1; i <= M; ++ i) { for (int j = 1; j <= M; ++ j) { dp[i][j] = 0LL; value[i][j] = 0LL; } } for (int i = 1; i <= M; ++ i) { value[i][i] = bit[i]; int flag = 0; for (int j = i+1; j <= M; ++ j) { value[i][j] = value[i][j-1] * 10LL + bit[j]; if (flag || value[i][j] >= 2147483648LL) { value[i][j] = 0LL; flag = 1; } } } for (int w = 1; w <= M; ++ w) { for (int s = 1; s <= M-w+1; ++ s) { int e = s+w-1; dp[s][e] = value[s][e]; for (int k = s; k < s+w-1; ++ k) { if (dp[s][e] < dp[s][k] + dp[k+1][e]) { dp[s][e] = dp[s][k] + dp[k+1][e]; } } } } printf("%lld\n", dp[1][M]); } return 0; }