求序列中长度不超过m的最大连续子序列的和
for (int i = 1; i <= n; i++) {scanf("%d", &a[i]);s[i] = s[i-1]+a[i];}q.push_back(0);for (int i = 1; i <= n; i++) {while (q.size() && q.front()<i-m)q.pop_front();ans = max(ans, s[i]-s[q.front()]);while (q.size() && s[q.back()]>=s[i])q.pop_back();q.push_back(i);}cout << ans << "\n";
在一个序列中找若干段子序列,每一段长度不能超过k,求能满足条件的最大点权和
//f[i]表示从前i个元素中选的最大合法方案数//状态转移方程f[i] = max(f[i-1], f[i-j+1]+s[i]-s[i-j]) = max(f[i-1],g[i-j]+s[i]); (1<=j<=k)//定义一个单调递减的队列维护g[i-j]使队头最大,由1<=j<=k可知要求的是长度为k的滑动窗口的最大值。int g(int i) {if (!i)return 0;return f[i-1]-s[i];}cin >> n >> k;for (int i = 1; i <= n; i++) {scanf("%d", &a[i]);s[i] = s[i-1]+a[i];}deque<int> q;q.push_back(0);for (int i = 1; i <= n; i++) {while (q.size() && q.front()<i-k)q.pop_front();f[i] = max(f[i-1], g(q.front())+s[i]);while (q.size() && g(q.back())<=g(i))q.pop_back();q.push_back(i);}cout << f[n] << "\n";
在一个序列中找若干个点,任意相邻两点间距离不能大于k,求能满足条件的最小点权和
//f[i]表示在前i个点中选第i个点的小合法方案数//状态转移方程f[i] = min(f[j])+w[i]; (i-k<=j<=i-1)//定义一个单调递增队列维护f[j]使队头最小cin >> n >> k;for (int i = 1; i <= n; i++)scanf("%d", &a[i]);deque<int> q;q.push_back(0);for (int i = 1; i <= n; i++) {if (q.front() < i-k)q.pop_front();f[i] = f[q.front()]+a[i];while (q.size() && f[q.back()] >= f[i])q.pop_back();q.push_back(i);}int ans = 0x3f3f3f3f;for (int i = n-k+1; i <= n; i++)ans = min(ans, f[i]);cout << ans << "\n";
二维滑动窗口(求大矩阵中固定小矩阵中的最值)
int n, m, k;int g[N][N];int row_min[N][N], row_max[N][N];void get_min(int a[], int b[], int tot) {deque<int> q;q.push_back(0);for (int i = 1; i <= tot; i++) {if (q.size() && q.front()<=i-k)q.pop_front();while (q.size() && a[q.back()]>=a[i])q.pop_back();q.push_back(i);b[i] = a[q.front()];}}void get_max(int a[], int b[], int tot) {deque<int> q;q.push_back(0);for (int i = 1; i <= tot; i++) {if (q.size() && q.front()<=i-k)q.pop_front();while (q.size() && a[q.back()]<=a[i])q.pop_back();q.push_back(i);b[i] = a[q.front()];}}int main() {cin >> n >> m >> k;for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)scanf("%d", &g[i][j]);for (int i = 1; i <= n; i++) {get_min(g[i], row_min[i], m);get_max(g[i], row_max[i], m);}int ans = INF;int a[N], b[N], c[N];for (int i = k; i <= m; i++) {for (int j = 1; j <= n; j++)a[j] = row_min[j][i];get_min(a, b, n);for (int j = 1; j <= n; j++)a[j] = row_max[j][i];get_max(a, c, n);for (int j = k; j <= n; j++)ans = min(ans, c[j]-b[j]);}cout << ans << "\n";return 0;}
