daimayuan 875 選元素 (單調佇列優化DP)
阿新 • • 發佈:2022-05-17
- f[i][l] 表示前i個元素,選l個,且當前位置選的最大值。
- f[i][l]從f[j][l - 1]轉移, i - k <= j < i,用單調佇列優化
- 不能有f[i][l] <-- f[i- 1][l] 這樣沒法控制每k個選一個
- 所以初始還要把f賦-1,f[0][0] = 0
#include<bits/stdc++.h> using namespace std; #define IOS ios::sync_with_stdio(false) ,cin.tie(0), cout.tie(0); //#pragma GCC optimize(3,"Ofast","inline") #define ll long long //#define int long long const int N = 3e3 + 5; const int M = 1e5 + 5; const int INF = 0x3f3f3f3f; const ll LNF = 0x3f3f3f3f3f3f3f3f; const ll mod = 998244353; const double PI = acos(-1.0); ll a[N], n, k; ll f[N][N]; int hh[N], tt[N], q[N][N]; ll que( int i, int l) { //int de1 = hh[l], de2 = tt[l]; while( hh[l] <= tt[l] && f[q[tt[l]][l]][l] <= f[i][l] ) -- tt[l]; //de1 = hh[l], de2 = tt[l]; q[++tt[l]][l] = i; //de1 = hh[l], de2 = tt[l]; while( hh[l] <= tt[l] && q[hh[l]][l] < i + 1 - k ) ++ hh[l]; //de1 = hh[l], de2 = tt[l]; return f[q[hh[l]][l]][l]; } int main () { IOS memset ( tt, -1, sizeof tt ); memset ( f, -1, sizeof f ); int x; cin >> n >> k >> x; // if( x < n / k ) { // cout << -1 << '\n'; return 0; // } f[0][0] = 0; for ( int i = 1; i <= n; ++ i ) cin >> a[i]; for ( int i = 1; i <= n; ++ i ) { for ( int l = 1; l <= min(x, i); ++ l ) { ll de = que(i - 1, l - 1); ll tmp = de >= 0 ? de + a[i] : -1; f[i][l] = tmp; } } ll ans = -1; for ( int i = n - k + 1; i <= n; ++ i ) { ans = max( ans, f[i][x]); } cout << ans << '\n'; return 0; }