标签:long def html algorithm 怎么 data http i++ cstring
一看这题---我能AC
看完这题---我要换题
这题第二问其实就是一个链的石子合并,也就是不用处理环
所以一三问怎么处理???
数组 mid[ i ][ j ] 记录区间 [ l , r ] 的断点
数组 le[ i ] 表示 a[i] 左边有几个左括号
数组 ri[ i ] 表示 a[i] 右边有几个右括号
递归处理一下括号数
单数字两边肯定不能有括号
我们在区间左右各标记上左右括号之后,继续向下递归,分别处理断开的两段区间
递归处理括号数
先输出数字周围的括号,再输出这个数字,注意每两个数字之间都是要有+连接的
然后输出最小合并
递归输出中间合并部分结果
合并左半部分的值,合并右半部分的值,两个部分一起合并的值
注意
(=的时候也是要更新一下mid的,可能是为了不断动态更新我编不动了)
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<string> #include<cstring> #include<cstdlib> #include<queue> using namespace std; typedef long long ll; inline int read() { int ans=0; char last=‘ ‘,ch=getchar(); while(ch<‘0‘||ch>‘9‘) last=ch,ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘) ans=ans*10+ch-‘0‘,ch=getchar(); if(last==‘-‘) ans=-ans; return ans; } int n,a[25],sum[25]; int f[25][25],mid[25][25]; int le[25],ri[25]; void cnt(int l,int r) { if(l==r) return ; le[l]++; ri[r]++; cnt(l,mid[l][r]); cnt(mid[l][r]+1,r); } void print(int l,int r) { if(l==r) return; print(l,mid[l][r]); print(mid[l][r]+1,r); printf("%d ",sum[r]-sum[l-1]); } int main() { n=read(); memset(f,0x7f,sizeof(f)); for(int i=1;i<=n;i++) a[i]=read(),sum[i]=sum[i-1]+a[i],f[i][i]=0; for(int l=2;l<=n;l++) for(int i=1;i+l-1<=n;i++){ int j=i+l-1; for(int k=i;k<j;k++){ if(f[i][k]+f[k+1][j]<=f[i][j]){ f[i][j]=f[i][k]+f[k+1][j]; mid[i][j]=k; } } f[i][j]+=sum[j]-sum[i-1]; } cnt(1,n); for(int i=1;i<=n;i++){ for(int j=1;j<=le[i];j++) printf("("); printf("%d",a[i]); for(int j=1;j<=ri[i];j++) printf(")"); if(i!=n) printf("+"); } printf("\n%d\n",f[1][n]); print(1,n); return 0; }
标签:long def html algorithm 怎么 data http i++ cstring
原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11913011.html