2維表table[i][j] 表示將序列a1,a2,a3,...中的包含aj在內的j 個數分成i段,能得到的最大值。
So, table[i][j] = table[i][j-1] + aj , 表示aj 與aj-1 同屬同一段。
若aj與aj-1不再同一段, 則 table[i][j] = max(table[i-1][k]) + aj , (i-1<=k<j)
求table第i行只需要用第i-1行,所以用動態數組來節省空間。
#include<iostream>
using namespace std;
const int M = 1000000;
long tmp[2][M];
int a[M];
inline long max(long &a ,long &b)
{
return a>b?a:b;
}
int main()
{
int m,n,t;
long max_,res;
while(scanf("%d%d",&m,&n)!=EOF)
{
t = 1 ;
for(int i = 0 ; i < n-m ;i ++)
{
cin >> a[i];
tmp[0][i] = 0;
}
for(int i = n-m; i < n ; i ++)
{
cin >> a[i];
}
for(int i = 0 ; i < m ;i++) // i=0 的時候表示的是分1塊的情況。
{
if(i == 0)
{
max_ = -32768l;
tmp[t][0] = a[0];
}
else
{
max_ = tmp[1-t][i-1];
tmp[t][i] = tmp[1-t][i-1]+a[i];
}
for(int j = i + 1 ; j <= n-m+i ; j++)
{
max_ = max(max_ , tmp[1-t][j-1]);
tmp[t][j] = max(max_ , tmp[t][j-1]) + a[j];
}
t = 1 - t;
}
t = 1 - t;
res = -32768*m;
for(int i = m-1 ; i < n ; i ++)
{
res =max(tmp[t][i],res);
}
cout << res << endl;
}
return 0;
}