四边形不等式第一题,口胡一下
我们原来的方程式:f[i][j]=sum[i][j]+max(f[i][k]+f[k+1][j]){i<=k<j}
那么,如果我们将最优的那个k记录下来,记为g[i][j],那么必然会有g[i][j-1]<=g[i][j]<=g[i+1][j]
当然这个东西成立是需要条件的,就是f[i][j']+f[i'][j]<=f[i][j]+f[i'][j'] (i<=i',j'<=j)
博主太弱上面两个都不会证明(只会证明sum[i][j]+sum[i'][j']<=sum[i][j']+sum[i'][j]),下面内容来自百度百科:
原来枚举k的时候需要从i~j现在只需要f[i][j-1]~f[i+1][j]就好了,这样是O(n^2)的(也不会证)
#pragma GCC opitmize("O3")
#pragma G++ opitmize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 2010
using namespace std;
int n,m,a[N],s[N],f[N][N],g[N][N];
int main(){
scanf("%d",&n); m=n<<1; memset(g,0x63,sizeof g);
for(int i=1;i<=n;++i) scanf("%d",a+i),a[i+n]=a[i];
for(int i=1;i<=m;++i) s[i]=s[i-1]+a[i],g[i][i]=0,f[i][i]=i;
for(int k=1;k<=m;++k)
for(int i=1,j;i+k<=m;++i){
j=i+k;
for(int x=f[i][j-1];x<=f[i+1][j];++x)
if(g[i][j]>g[i][x]+g[x+1][j]){ g[i][j]=g[i][x]+g[x+1][j]; f[i][j]=x; }
g[i][j]+=s[j]-s[i-1];
}
for(int i=1;i<=n;++i) **g=min(**g,g[i][i+n-1]);
printf("%d\n",**g); memset(g,0,sizeof g);
for(int i=1;i<=m;++i) g[i][i]=0,f[i][i]=i;
for(int k=1;k<=m;++k)
for(int i=1,j;i+k<=m;++i){
j=i+k;
for(int x=f[i][j-1];x<=f[i+1][j];++x)
if(g[i][j]<g[i][x]+g[x+1][j]){ g[i][j]=g[i][x]+g[x+1][j]; f[i][j]=x; }
g[i][j]+=s[j]-s[i-1];
}
for(int i=1;i<=n;++i) **g=max(**g,g[i][i+n-1]);
printf("%d\n",**g);
}