#include <cstdio> #include <cstring> using namespace std; const int maxn = 25; int n, dp[maxn][maxn], gap[maxn][maxn];//g is the breakpoint position int ll[maxn], rr[maxn];//Number of left/right parentheses of the number at this position int a[maxn], sum[maxn];//Number, prefix sum void dfs2(int x, int y); void dfs1(int x, int y); intmain() { scanf("%d", &n); int i, j, len, l, r, k; sum[0] = 0; memset(dp, 0x3f, sizeof(dp)); for(i = 1; i <= n; ++i) { scanf("%d", &a[i]); sum[i] = sum[i-1]+a[i]; dp[i][i] = 0; // keep in mind } for (len = 2; len <= n; ++ len) for(l = 1; l+len-1 <= n; ++l) { r = l + len - 1; for(k = l; k < r; ++k) { int tmp = dp[l][k]+dp[k+1][r]+sum[r]-sum[l-1]; if(tmp <= dp[l][r]) {//Here is <=, not <, as far as possible to add parentheses, because n-1 parentheses need to be filled dp[l][r] = tmp; gap[l][r] = k; } } } dfs1(1, n);//Seek ll[] and rr[] for(i = 1; i <= n; ++i) { for(j = 1; j <= ll[i]; ++j) printf("("); printf("%d", a[i]); if(!rr[i] && i != n) printf("+"); for(j = 1; j <= rr[i]; ++j) printf(")"); if(rr[i] && i != n) printf("+"); } printf("\n%d\n", dp[1][n]); dfs2(1, n); return 0; } void dfs1(int x, int y) { if(x == y) return; ++ll[x],++rr[y]; dfs1(x, gap[x][y]); dfs1(gap[x][y]+1, y); } void dfs2(int x, int y) { if(x == y) return; dfs2(x, gap[x][y]); dfs2(gap[x][y]+1, y); printf("%d ", sum[y]-sum[x-1]); }
Luogu P2308_Interval dp_Output Path and Intermediate Process
Guess you like
Origin http://43.154.161.224:23101/article/api/json?id=325726121&siteId=291194637
Ranking