「luogu1880」[NOI1995]石子合并

朴素算法O(n^3) 可用四边形不等式优化到O(n^2)

1
#include<bits/stdc++.h> 2 using namespace std; 3 const int N=210,oo=2e9; 4 int n,a[N],f[N][N],p[N][N],ans1=oo,ans2; 5 int main(){ 6 scanf("%d",&n); 7 for(int i=1;i<=n;i++) scanf("%d",&a[i]),a[i+n]=a[i]; 8 for(int i=1;i<=(n<<1);i++) a[i]+=a[i-1]; 9 memset(f,127/3,sizeof(f)); 10 for(int i=1;i<=(n<<1);i++) f[i][i]=0,p[i][i]=i; 11 for(int i=2;i<=n;i++) 12 for(int j=1;j+i-1<=(n<<1);j++){ 13 for(int k=p[j][i+j-2];k<=p[j+1][i+j-1];k++) 14 if(f[j][i+j-1]>f[j][k]+f[k+1][i+j-1]+a[i+j-1]-a[j-1]) f[j][i+j-1]=f[j][k]+f[k+1][i+j-1]+a[i+j-1]-a[j-1],p[j][i+j-1]=k; 15 if(i==n) ans1=min(ans1,f[j][i+j-1]); 16 } 17 memset(f,0,sizeof(f)); 18 for(int i=2;i<=n;i++) 19 for(int j=1;i+j-1<=(n<<1);j++){ 20 f[j][i+j-1]=max(f[j][i+j-2],f[j+1][i+j-1])+a[i+j-1]-a[j-1]; 21 if(i==n) ans2=max(ans2,f[j][i+j-1]); 22 } 23 printf("%d\n%d",ans1,ans2); 24 return 0; 25 }

 

posted @ 2018-03-08 13:22  Cupcake  阅读(141)  评论(0编辑  收藏  举报