滑動視窗+dp
很有意思找最小花費
用雙向佇列維護,仔細看看想想
每一次跑都從頭跑,然後去排掉大的花銷
dp思想
Problem - E - Codeforces
#include <bits/stdc++.h> //#pragma GCC optimize("Ofast") #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <cmath> //#define double long double #define int long long #define endl '\n' using namespace std; const int N=2e5+5,M=1e9+7; const int INF = 0x3f3f3f3f; const int mod=998244353; typedef pair<int,int> PII; int a[105][N]; void solve() { int n,m,k,d; cin>>n>>m>>k>>d; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cin>>a[i][j]; } } vector<int> sum; for(int i=1;i<=n;i++) { deque<int> q; int dp[m+2]; dp[1]=1; q.push_back(1); for(int j=2;j<=m;j++) { while (!q.empty() && j-q.front()-1>d) q.pop_front(); dp[j]=dp[q.front()]+a[i][j]+1; while (!q.empty() && dp[q.back()]>dp[j]) { q.pop_back(); } q.push_back(j); } sum.push_back(dp[m]); } int pp[N]; pp[0]=sum[0]; for(int i=1;i<sum.size();i++) { pp[i]=pp[i-1]+sum[i]; } int ans=pp[k-1]; for(int i=k;i<sum.size();i++) { ans=min(ans,pp[i]-pp[i-k]); } cout<<ans<<endl; } signed main(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int T=1; cin>>T; while(T--){ solve(); } return 0; }