题目
将一个数字串拆分成不超过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;
}