题解:
参考 https://www.luogu.com.cn/blog/12cow/SBCOI2020
从i到i-1,dp[k+1][j]与dp[i][k]交点左移,deque后端pop,需要多考虑i-1这个点,比较后加到deque前端。
#include <bits/stdc++.h> # define LL long long using namespace std; const LL INF=200000000000000; LL dp[7001][7001]; LL arr[7001]; deque<int> dq; int dqs[7001][7001]; int read(){ int res=0; char c=getchar(); while(c<'0' || c>'9') c=getchar(); while(c>='0' && c<='9'){ res=res*10+(c-'0'); c=getchar(); } return res; } int main(){ int T=read(); while(T--){ int n=read(); for(int i=1;i<=n;i++) arr[i]=read(); for(int j=1;j<=n;j++){ dq.clear(); int k=j-1; for(int i=j-1;i>=0;i--){ dp[i][j]=INF; while(k>=i && dp[k+1][j]<=dp[i][k]) k--; while(!dq.empty() && dq.back()>k) dq.pop_back(); while(!dq.empty() && dp[i+1][j]+arr[i]<dp[dq.front()+1][j]+arr[dq.front()]) dq.pop_front(); dq.push_front(i); dp[i][j]=min(dp[i][j],dp[dq.back()+1][j]+arr[dq.back()]); dp[i][j]=min(dp[i][j],dp[i][k+1]+arr[k+1]); } } printf("%lld ", dp[1][n]); } return 0; }