Enter an integer n, which indicates that there are n data records. Input n data records and obtain the largest sum of m substrings;
Dp [I] [j] indicates the largest and largest substring in the I field when combined with the number of j;
Note: dp [I] [j] is not the number of the first j, which forms the largest sum of the I segments;
Unoptimized code:
#include
using namespace std ;#define max(x,y) ((x) > (y) ? (x) : (y))int main(){int m , n ;cin >> m >> n ;int a[100] ;int i ;for( i = 1 ; i <= n ; i++ )cin >> a[i] ;int dp[100][100] = {0} ;for( i = 1 ; i <= m ; i++)for(int j = i ; j <= n ; j++){int max1 = -1000000 ;for(int k = i - 1 ; k < j ; k++ )max1 = max(max1,dp[i-1][k]) ;if(max1 > dp[i][j-1])dp[i][j] = max1 + a[j] ;elsedp[i][j] = dp[i][j-1] + a[j] ;}int max2 = -1000000 ;for( i = 1 ; i <= n ; i++)max2 = max(max2,dp[m][i]) ;cout << max2 << endl ;return 0 ;}
The time complexity of the above program is O (n ^ 3) n, which can be or, which indicates that this program needs to be simplified; everything requires a process from complexity to simplicity, only in this way can you better remember and improve your individual abilities ......
As can be seen from the above program, for each increase of a number, the maximum value of the previous time is required, so you can solve this problem by using a variable to store the maximum value.
#include
using namespace std ;#define max(x,y) ((x) > (y) ? (x) : (y))int main(){int m , n ;cin >> m >> n ;int a[100] ;int i ;for( i = 1 ; i <= n ; i++ )cin >> a[i] ;int dp[100][100] = {0} ;for( i = 1 ; i <= m ; i++){int max1 = -1000000 ;for(int j = i ; j <= n ; j++){max1 = max(max1,dp[i-1][j-1]) ;if(max1 > dp[i][j-1])dp[i][j] = max1 + a[j] ;elsedp[i][j] = dp[i][j-1] + a[j] ;}}int max2 = -1000000 ;for( i = 1 ; i <= n ; i++)max2 = max(max2,dp[m][i]) ;cout << max2 << endl ;return 0 ;}
With this slight modification, the time complexity of the program can be changed from O (n ^ 3) to O (n ^ 2), which is a great improvement, the next step is to optimize the space complexity;
Since the value of dp [I] [j] is only related to dp [I] [J-1] and dp [I-1] [J-1], only two rows are required, this directly saves several 100,000 times of space, so we can conclude that a good algorithm requires not only correct results, but also high space utilization and speed ......
#include
using namespace std ;#define max(x,y) ((x) > (y) ? (x) : (y))int main(){int m , n ;cin >> m >> n ;int a[100] ;int i ;for( i = 1 ; i <= n ; i++ )cin >> a[i] ;int dp[2][1005] = {0} ;int t = 1 ;for( i = 1 ; i <= m ; i++){int max1 = -1000000 ;int t = !t ;for(int j = i ; j <= n ; j++){max1 = max(max1,dp[t][j-1]) ;if(max1 > dp[!t][j-1])dp[!t][j] = max1 + a[j] ;elsedp[!t][j] = dp[!t][j-1] + a[j] ;}}int max2 = -1000000 ;for( i = 1 ; i <= n ; i++)max2 = max(max2,dp[m&1][i]) ;cout << max2 << endl ;return 0 ;}