区间dp-洛谷P2308 添加括号

来源:互联网 发布:synchronization java 编辑:程序博客网 时间:2024/06/05 08:12

https://www.luogu.org/problem/show?pid=2308#sub
就是区间dp;
因为一定要加n-1个括号;
输出答案的时候和加分二叉树一样;
然后从左到右是指让括号靠又,所以k尽可能靠右;

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#define Ll long longusing namespace std;int a[50],h[50],hh[50],f[50][50],g[50][50],sum[51];int n,m;void dfs(int x,int y){    if(x==y)return;    h[x]++;    hh[y]++;    dfs(x,g[x][y]);    dfs(g[x][y]+1,y);}void DFS(int x,int y){    if(x==y)return;    DFS(x,g[x][y]);    DFS(g[x][y]+1,y);    cout<<sum[y]-sum[x-1]<<' ';}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++){        scanf("%d",&a[i]);        f[i][i]=0;    }    for(int i=1;i<=n;i++)        sum[i]=sum[i-1]+a[i];    for(int i=n-1;i;i--)    for(int j=i+1;j<=n;j++)    {        f[i][j]=1e9;        for(int k=i;k<j;k++){            if(f[i][k]+f[k+1][j]+sum[j]-sum[i-1]<=f[i][j]){                f[i][j]=f[i][k]+f[k+1][j]+sum[j]-sum[i-1];                g[i][j]=k;            }        }    }    dfs(1,n);    for(int i=1;i<=n;i++){        for(int j=1;j<=h[i];j++)cout<<'(';        cout<<a[i];        if(!hh[i]&&i!=n)cout<<'+';        for(int j=1;j<=hh[i];j++)cout<<')';        if(hh[i]&&i!=n)cout<<'+';    }cout<<endl;    cout<<f[1][n]<<endl;    DFS(1,n);}
1 0
原创粉丝点击