题意:From https://www.cnblogs.com/CXCXCXC/p/4725249.html
思路:本身就两维状态了,把问题关键s[i][j]写成二维比一维好写多了
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef long double ld; 7 typedef pair<int,int> PII; 8 typedef pair<ll,ll> Pll; 9 typedef vector<int> VI; 10 typedef vector<PII> VII; 11 //typedef pair<ll,ll>P; 12 #define N 2010 13 #define M 200010 14 #define INF 1e9 15 #define fi first 16 #define se second 17 #define MP make_pair 18 #define pb push_back 19 #define pi acos(-1) 20 #define mem(a,b) memset(a,b,sizeof(a)) 21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 23 #define lowbit(x) x&(-x) 24 #define Rand (rand()*(1<<16)+rand()) 25 #define id(x) ((x)<=B?(x):m-n/(x)+1) 26 #define ls p<<1 27 #define rs p<<1|1 28 29 const ll MOD=1e9+7,inv2=(MOD+1)/2; 30 double eps=1e-6; 31 int dx[4]={-1,1,0,0}; 32 int dy[4]={0,0,-1,1}; 33 34 int dp[N][N],s[N][N],a[N]; 35 36 int read() 37 { 38 int v=0,f=1; 39 char c=getchar(); 40 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 41 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 42 return v*f; 43 } 44 45 int main() 46 { 47 //freopen("1.in","r",stdin); 48 int m=read(),n=read(); 49 rep(i,1,n) a[i]=read(); 50 rep(i,1,n) 51 rep(j,i,n) s[i][j]=s[i][j-1]+a[j]+(j!=i); 52 rep(i,0,n+1) 53 rep(j,0,n+1) dp[i][j]=INF; 54 rep(i,1,n) 55 if(s[1][i]<=m) dp[1][i]=0; 56 rep(i,2,n) 57 { 58 int k=i,mn=INF; 59 rep(j,i,n) 60 if(s[i][j]<=m) 61 { 62 while(k>1&&s[k-1][i-1]<=s[i][j]) 63 { 64 k--; 65 mn=min(mn,dp[k][i-1]-s[k][i-1]); 66 } 67 dp[i][j]=mn+s[i][j]; 68 } 69 k=1,mn=INF; 70 per(j,n,0) 71 if(s[i][j]<=m) 72 { 73 while(k<=i&&s[i][j]<=s[k][i-1]) 74 { 75 mn=min(mn,dp[k][i-1]+s[k][i-1]); 76 k++; 77 } 78 dp[i][j]=min(dp[i][j],mn-s[i][j]); 79 } 80 } 81 int ans=INF; 82 rep(i,1,n) ans=min(ans,dp[i][n]); 83 printf("%d ",ans); 84 return 0; 85 }