其他分享
首页 > 其他分享> > P1880 [NOI1995]石子合并[区间dp+四边形不等式优化]

P1880 [NOI1995]石子合并[区间dp+四边形不等式优化]

作者:互联网

P1880 [NOI1995]石子合并


 

丢个地址就跑(关于四边形不等式复杂度是n方的证明)

嗯所以这题利用决策的单调性来减少k断点的枚举次数。具体看lyd书。这部分很生疏,但是我还是选择先不管了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 typedef double db;
 5 template<typename T>inline char MIN(T&A,T B){return A>B?A=B,1:0;}
 6 template<typename T>inline char MAX(T&A,T B){return A<B?A=B,1:0;}
 7 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
 8 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
 9 template<typename T>inline T read(T&x){
10     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
11     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
12 }
13 const int N=200+7,INF=0x3f3f3f3f;
14 int p[N][N],Fmin[N][N],Fmax[N][N],sum[N],a[N];
15 int n;
16 
17 int main(){//freopen("tmp.in","r",stdin);freopen("tmp.out","w",stdout);
18     read(n);
19     for(register int i=1;i<=n;++i)a[i+n]=read(a[i]);
20     for(register int i=1;i<(n<<1);++i)sum[i]=sum[i-1]+a[i],p[i][i]=i;
21     for(register int i=(n<<1)-1;i;--i){
22         for(register int j=i+1;j<(n<<1);++j){
23             Fmax[i][j]=_max(Fmax[i+1][j],Fmax[i][j-1])+sum[j]-sum[i-1];Fmin[i][j]=INF;
24             for(register int k=p[i][j-1];k<=p[i+1][j];++k)
25                 if(MIN(Fmin[i][j],Fmin[i][k]+Fmin[k+1][j]+sum[j]-sum[i-1]))p[i][j]=k;
26             if(!(Fmin[i][j]^INF))Fmin[i][j]=0; 
27         }
28     }
29     Fmin[0][0]=INF;
30     for(register int i=1;i<=n;++i)MIN(Fmin[0][0],Fmin[i][i+n-1]),MAX(Fmax[0][0],Fmax[i][i+n-1]);
31     printf("%d\n%d\n",Fmin[0][0],Fmax[0][0]);
32     return 0;
33 }

 

标签:templateinline,return,int,NOI1995,P1880,char,isdigit,dp,getchar
来源: https://www.cnblogs.com/saigyouji-yuyuko/p/10486298.html