N 组连续子串最大和
數組 a 中有 M 個數 , 將 M 個數分成 N 組 , 并且每組中的數據順序和原數組中的順序保持一致,求 N 組中的數據之和最大為多少?
向 dp 數組中賦初始值 ,如果 M == N ,則 dp[ i ][ i ] = dp[ i - 1 ][ i - 1 ] + a[ i ] ;
若N為1時 ,即為求連續子串最大和問題;
假設dp[ 1 ][ i ] ( 2 =< i <= M) 代表 與第 i 個數組成連續子串的最大和,當dp[ 1 ][ i - 1 ] < 0 時 , a[ i ] 獨立作為一個子串 , 即 dp[ 1 ][ i ] = max ( dp[ 1 ][ i -1 ] + a[ i ] , a[ i ] ) ;很需要注意的一點是:dp[ 1 ][ i ] 不一定是 i 個數中連續子串的最大和。
分別求出數組中有一個數、兩個數、三個數……M個數中連續子串的最大和,用dp[ i ][ 1 ] 來表示;
若N為2時,表示將M個數分成 2 組 ,求兩組數中的和最大 ;
dp[ 2 ][ i ] ( 3 =< i <= M ) 代表 與第 i 個數組成連續子串,形成兩個連續子串中,第2個子串的最大和;
可知,第二個子串可以單獨成為一段,最終形成兩段,也可以和上一個段一起形成一段,最終形成兩段;
所以 dp[M][N] ?代表 與第M個數組成的連續子串的最大和,但不一定是 M 個數中連續子串的最大和 ;
與第 M 個數組成連續子串時 ,第 M 個數可以與第 M-1 個數組成的子串組合,也可以獨立作為一個子串 , 與 ?M-1 個數組成的(N-1)組連續子串中最大和組合 ,才能達到分成 N 組的效果;
最后輸出dp數組中最大值,即為 N 組中數據之和的最大值;
?
下面給出相應的代碼:
#include<iostream> using namespace std ; #define M 100005 #define max(x,y) ((x) > (y) ? (x) : (y)) int a[ M ] , dp[ M ][ M ] ; int main() {int k , n ;while(cin >> k >> n) {int i ;for(i = 1 ; i <= n ; i++)cin >> a[i] ;memset(dp,0,sizeof(dp)) ;for(i = 1 ; i <= k ; i++) {dp[i][i] = dp[i-1][i-1] + a[i] ;dp[i-1][i] = max(dp[i-1][i],dp[i-1][i-1]) ;for(int j = i + 1 ; j <= n ; j++) {dp[i][j] = max(dp[i-1][j-1]+a[j],dp[i][j-1]+a[j]) ;dp[i-1][j] = max(dp[i-1][j],dp[i-1][j-1]) ;}}int max1 = -(1<<30) ;for(i = k ; i <= n ; i++)max1 = max(max1,dp[k][i]) ;cout << max1 << endl ;}return 0 ; }?
上面的代碼空間復雜度比較高,但通過觀察可以得到,依照滾動數組的思想,讓dp數組的行數為2,在兩行中循環,這樣輕易一改,省去了很多空間:
有木有很強大!!! ? ? ?思維決定到效率!!!
?
#include<iostream> using namespace std ; #define M 100005 #define max(x,y) ((x) > (y) ? (x) : (y)) int a[ M ] , dp[ 2 ][ M ] ; int main() {int k , n ;while(cin >> k >> n) {int i ;for(i = 1 ; i <= n ; i++)cin >> a[i] ;memset(dp,0,sizeof(dp)) ;int t = 0 ;for(i = 1 ; i <= k ; i++) {t = !t ;dp[t][i] = dp[!t][i-1] + a[i] ;dp[!t][i] = max(dp[!t][i],dp[!t][i-1]) ;for(int j = i + 1 ; j <= n ; j++) {dp[t][j] = max(dp[!t][j-1]+a[j],dp[t][j-1]+a[j]) ;dp[!t][j] = max(dp[!t][j],dp[!t][j-1]) ;}}int max1 = -(1<<30) ;for(i = k ; i <= n ; i++)max1 = max(max1,dp[k&1][i]) ;cout << max1 << endl ;}return 0 ; }?
?
?
轉載于:https://www.cnblogs.com/scottding/p/3613166.html
總結
以上是生活随笔為你收集整理的N 组连续子串最大和的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蓝桥杯 第三届C/C++预赛真题(7)
- 下一篇: 历届试题 密码发生器