1.
一維陣列求最大子段和;(hdu1003,hoj1760)
這就是最基礎的最大子段和模型:給出乙個序列a[0],a[1],a[2],...a[n],要求出連續的一段,使其總和最大.如果設dp[i]表示以第i個元素為結尾的最大總和,那麼顯然有:
dp[i] = dp[i - 1] + a[i] (dp[i - 1] > 0 時)
a[i]
(dp[i - 1] < 0 時)
顯然這個模型空間複雜度可以壓縮至o(1),即:
dp += a[i] (dp > 0)
dp = a[i] (dp < 0)
//ac(含有最大和的起始位置和終止位置)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include //基本輸入流
#include //基本輸出流
#include //基於字串的流
#include //stl 通用模板類
#include //複數處理
#include //浮點環境
#include //整數格式轉換
#include //布林環境
#include //整型環境
#include //通用型別數學巨集
#define l(a,b,c) for(int a = b;a >= c;a --)
#define m(a,b,c) for(int a = b;a <= c;a ++)
#define n(a,b) memset(a,b,sizeof(a));
const int max=1<<30;
const int min=-max;
using namespace std;
int dp[100011],a[100011];
int main()
if(max>0)
printf("the maximum winning streak is %d.\n",max);
else
printf("losing streak.\n");
}return 0;}
2.最大m子段和(hdu1024 , poj2479)
已知有n個數,求m段不相交的子段權值之和最大,
狀態轉移方程:dp[i][j]表示以i為結尾元素的j個子段的數和
dp[i][j]=max(dp[i-1][j]+a[i],dp[i-k][j-1]+a[i]);其中(j-1<=k<=n-m+1)
此題實現這種思想:
for(i=1;i<=m;i++)}}
//ac
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include //基本輸入流
//#include //基本輸出流
//#include //基於字串的流
//#include //stl 通用模板類
//#include //複數處理
//#include //浮點環境
//#include //整數格式轉換
//#include //布林環境
//#include //整型環境
//#include //通用型別數學巨集
#define l(a,b,c) for(int a = b;a >= c;a --)
#define m(a,b,c) for(int a = b;a <= c;a ++)
#define n(a,b) memset(a,b,sizeof(a));
#define maxx(a,b) ((a)>(b)?a:b)
#define minn(a,b) ((a)<(b)?a:b)
const int max=1<<30;
const int min=-max;
const int n=1001000;
using namespace std;
int a[n],pre[n],num[n];
int main()
}cout<
//ac
(用c++輸入超時)
#include
#include
#include
#include
#include
#include
#include
#include
#define l(a,b,c) for(int a = b;a >= c;a --)
#define m(a,b,c) for(int a = b;a <= c;a ++)
#define n(a,b) memset(a,b,sizeof(a));
#define maxx(a,b) ((a)>(b)?a:b)
#define minn(a,b) ((a)<(b)?a:b)
const int max=1<<30;
const int min=-max;
const int n=50005;
using namespace std;
int a[n],pre[n],num[n];
int main()
}cout< 3.
最大子矩陣和
所謂萬變不離其宗,這個的思路和上面是一樣的. 維數增加了一維,所以可以考慮把它轉化成一維的"基本問題". 我們可以先統計sum[i][j](以下假設下標從1開始) : 第i行,從開頭到第j個元素的總值,這樣, 第i行從第j個元素到第k個元素的總價值就是sum[i][k] - sum[i][j - 1]. 這個預處理的時間複雜度是o(n^2). 這時,這個問題就轉化成了一維的最大子段和問題了: 列舉每一行中,第i到第j個元素(1 <= i <= j <= n),就可以把j - i + 1個元素的總和看成乙個元素(轉化的過程), 然後,對n個這樣的元素求最大子段和即可. 這一部分的時間複雜度是o(n^3),因此總複雜度也為o(n^3).
//ac
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include //基本輸入流
//#include //基本輸出流
//#include //基於字串的流
//#include //stl 通用模板類
//#include //複數處理
//#include //浮點環境
//#include //整數格式轉換
//#include //布林環境
//#include //整型環境
//#include //通用型別數學巨集
#define l(a,b,c) for(int a = b;a >= c;a --)
#define m(a,b,c) for(int a = b;a <= c;a ++)
#define n(a,b) memset(a,b,sizeof(a));
#define maxx(a,b) ((a)>(b)?a:b)
#define minn(a,b) ((a)<(b)?a:b)
const int max=1<<30;
const int min=-max;
using namespace std;
int dp[111][111],a[111][111];
int main()
}int ans,max=min;
m(i,1,n) //每一行的起始位置}}
cout<
4.最大子立方體
最大子段和 (dp
n個整數組成的序列a1,a2,a3,ann,求該序列如ai ai 1 aj的連續子段和的最大值。當所給的整數均為負數時和為0。例如 2,11,4,13,5,2,和最大的子段為 11,4,13。和為20。第1行 整數序列的長度n 2 n 50000 第2 n 1行 n個整數 10 9 ai 10 9 ...
dp 最大子段和
注意 在實際問題中可能題目要求至少選乙個,可能可以乙個都不選 只返回最大子段和 include include using namespace std const int maxn 2e5 10 const int inf 0x7fffffff int n int a maxn int maxsum...
最大子段和(dp)
最基礎的的最大子段和,設dp i dp i dp i 為以num i num i num i 結尾的最大子段和,有dp i m ax d p i 1 n um i nu m i dp i max dp i 1 num i num i dp i max dp i 1 num i n um i 最終結果...