【BZOJ1521】Est(单调队列优化DP)

题意: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\n",ans);
84     return 0;
85 }

 

posted on 2019-10-25 23:23  myx12345  阅读(220)  评论(0编辑  收藏  举报

导航