题目描述
$visit\text{_}world$发现有下优化问题可以用很平凡的技巧解决,所以他给你分享了这样一道题:
现在有长度为$N$的整数序列$\{ a_i\}$,你需要从中选出$K$个不想叫的连续子区间(可以存在元素不被选),从左到右记它们的和为$s_1,s_2,...,s_k$,我们的优化目标是最大化下述和式:
$$\sum \limits_{i=1}^{k-1}|s_i-s_{i+1}|$$
你只需要输出这个最大的和即可。
输入格式
第一行两个整数$N,K$,意义如上。
接下来一行$N$个整数,第$i$个数表示$a_i$,保证有$|a_i|\leqslant 10^4$。
输出格式
输出一行一个整数,表示答案。
样例
样例输入:
5 3
5 2 4 3 1
样例输出:
12
数据范围与提示
样例解释:
选择$(5),(2,4,3),(1)$三个子段,$|5-9|+|9-1|=12$
数据范围:
对于全部的测试数据,保证$N\leqslant 3\times 10^4,K\leqslant \min(N,200)$。
$\bullet$子任务$1$($10$分):$K\leqslant 3$。
$\bullet$子任务$2$($30$分):$N\leqslant 400,K\leqslant 50$。
$\bullet$子任务$3$($20$分):$N\leqslant 10^3,K\leqslant 100$。
$\bullet$子任务$4$($40$分):无特殊限制。
题解
利用贪心思想,这$k$个序列一定是一高一低的,不可能连续三个及以上持续上升或下降。
对于高的序列,其贡献为$+2$;对于低的序列,其贡献为$-2$;而中间也会有一些并不选的状态,其贡献为$0$,而对于这些状态,其接下来会有高或低的序列,为了区分它们,不妨将其称为上升状态$or$下降状态。
考虑$DP$,设$dp[i][j][0/1/2/3]$表示前$i$个数,分成了$j$段,当前状态是高、低、上升、下降状态。
状态转移很简单,需要注意的是对于边界的处理,即$j=1$和$j=K$的情况。
时间复杂度:$\Theta(NK)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h> using namespace std; int N,K; int w[30001]; int dp[30001][201][4]; int main() { scanf("%d%d",&N,&K); for(int i=1;i<=N;i++) scanf("%d",&w[i]); memset(dp,-0x3f,sizeof(dp)); for(int i=1;i<=N;i++)dp[i][0][0]=dp[i][0][1]=dp[i][0][2]=dp[i][0][3]=0; dp[0][0][0]=dp[0][0][1]=dp[0][0][2]=dp[0][0][3]=0; for(int i=1;i<=N;i++) { dp[i][1][0]=max(dp[i-1][1][0],dp[i-1][0][2])+w[i]; dp[i][1][1]=max(dp[i-1][1][1],dp[i-1][0][3])-w[i]; dp[i][1][2]=max(dp[i-1][1][2],dp[i][1][1]); dp[i][1][3]=max(dp[i-1][1][3],dp[i][1][0]); dp[i][K][0]=max(dp[i-1][K][0],dp[i-1][K-1][2])+w[i]; dp[i][K][1]=max(dp[i-1][K][1],dp[i-1][K-1][3])-w[i]; dp[i][K][2]=max(dp[i-1][K][2],dp[i][K][1]); dp[i][K][3]=max(dp[i-1][K][3],dp[i][K][0]); for(int j=2;j<K;j++) { dp[i][j][0]=max(dp[i-1][j][0],dp[i-1][j-1][2])+2*w[i]; dp[i][j][1]=max(dp[i-1][j][1],dp[i-1][j-1][3])-2*w[i]; dp[i][j][2]=max(dp[i-1][j][2],max(dp[i][j][1],dp[i-1][j-1][2])); dp[i][j][3]=max(dp[i-1][j][3],max(dp[i][j][0],dp[i-1][j-1][3])); } } printf("%d",max(dp[N][K][2],dp[N][K][3])); return 0; }
rp++
原文地址:https://www.cnblogs.com/wzc521/p/11743598.html