UVa 11258 - String Partition

匿名 (未验证) 提交于 2019-12-02 22:56:40
版权声明:本文为博主原创文章,未经博主允许不得转载。 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; } 
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!