EZOJ #227
分析
我们发现第一段数和最后一段数对答案的贡献系数为1/-1,其余为0/2/-2
而且对于相邻两段不能系数均非0
于是可以dp
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
const int inf = 1e9+7;
int dp[30010][210][4];
int main(){
int n,m,i,j,k,x;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
for(j=0;j<4;j++)
dp[0][i][j]=-inf;
for(i=1;i<=n;i++){
scanf("%d",&x);
for(j=1;j<=m;j++){
k=2-((j==1)||(j==m));
dp[i][j][0]=max(dp[i-1][j][0],dp[i-1][j-1][3])-k*x;
dp[i][j][1]=max(dp[i-1][j][1],dp[i][j][0]);
dp[i][j][2]=max(dp[i-1][j][2],dp[i-1][j-1][1])+k*x;
dp[i][j][3]=max(dp[i-1][j][3],dp[i][j][2]);
if(k>1){
dp[i][j][1]=max(dp[i][j][1],dp[i-1][j-1][1]);
dp[i][j][3]=max(dp[i][j][3],dp[i-1][j-1][3]);
}
}
}
cout<<max(dp[n][m][1],dp[n][m][3]);
return 0;
}