单调队列优化dp模板题
#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long LL;
const int maxn = 10;
const int maxm = 100005;
LL T[maxn][maxm];
LL dp[maxm][maxn],sum[maxm][maxn];
typedef pair<LL,int> pii;
deque<pii> que[maxn];
int main(){
int m,n,k,L;
scanf("%d%d%d%d",&m,&n,&k,&L);
for( int i = 1;i <= n;i++ ){
que[i].push_back( pii( 0,0 ) );
for( int j = 1;j <= m;j++ ){
scanf("%lld",&T[i][j]);
sum[j][i] = sum[j-1][i] + T[i][j];
}
}
LL ans = 0x3f3f3f3f3f3f;
for( int i = 1;i <= m;i++ ){
int dt = min( i,L );
for( int j = 1;j <= n;j++ ) {
while (que[j].size() && que[j].front().se < i - dt) que[j].pop_front();
dp[i][j] = que[j].front().fi + k + sum[i][j];
if( i == m ) ans = min( ans,dp[i][j]-k );
}
for( int j = 1;j <= n;j++ ){
for( int k = 1;k <= n;k++ ){
if( k == j ) continue;
LL x = dp[i][j] - sum[i][k];
while( que[k].size() && que[k].back().fi >= x ) que[k].pop_back();
que[k].push_back( pii(x,i) );
}
}
}
printf("%lld",ans);
return 0;
}