E56【模板】四边形不等式优化DP 石子合并

视频链接:471 四边形不等式优化DP 【模板】石子合并_哔哩哔哩_bilibili

 

Luogu P1775 石子合并(弱化版)

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=310;
int n, a[N], s[N];
int f[N][N]; //f[i,j]表示合并区间[i,j]的石子的最小代价 

int main(){
  memset(f,0x3f,sizeof(f)); cin>>n;
  for(int i=1;i<=n;i++)
    cin>>a[i], s[i]=s[i-1]+a[i], f[i][i]=0;
  
  for(int len=2; len<=n; len++)         //区间长度
    for(int i=1,j; (j=i+len-1)<=n; i++) //区间端点
      for(int k=i; k<j; k++)            //区间分割点
        if(f[i][j]>f[i][k]+f[k+1][j]+s[j]-s[i-1])
          f[i][j]=f[i][k]+f[k+1][j]+s[j]-s[i-1];
  cout<<f[1][n];
}

 

// 四边形不等式优化
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=1010;
int n, a[N], s[N];
int f[N][N]; //f[i,j]表示合并区间[i,j]的石子的最小代价
int p[N][N]; //p[i,j]记录区间[i,j]的最优分割点

int main(){
  memset(f,0x3f,sizeof(f)); cin>>n;
  for(int i=1; i<=n; i++)
    cin>>a[i],s[i]=s[i-1]+a[i],f[i][i]=0,p[i][i]=i;
  
  for(int len=2; len<=n; len++)               //区间长度
    for(int i=1,j; (j=i+len-1)<=n; i++)       //区间端点
      for(int k=p[i][j-1]; k<=p[i+1][j]; k++) //区间分割点
        if(f[i][j]>f[i][k]+f[k+1][j]+s[j]-s[i-1])
          f[i][j]=f[i][k]+f[k+1][j]+s[j]-s[i-1], p[i][j]=k;
  cout<<f[1][n];
}

 

posted @ 2023-05-16 15:55  董晓  阅读(308)  评论(0编辑  收藏  举报