vijos 1038 括号+路径 ***
链接:点我
就是自己写不出来
1 #include <cstdio> 2 #include <climits> 3 #include <memory.h> 4 using namespace std; 5 const int MAX = 23; 6 7 int dp[MAX][MAX]; 8 int pos[MAX][MAX]; 9 int val[MAX], sum[MAX][MAX]; 10 11 void print_path(int i, int j){ 12 if(i == j){ 13 printf("%d", val[i]); 14 return; 15 } 16 printf("("); 17 print_path(i, pos[i][j]); 18 printf("+"); 19 print_path(pos[i][j] + 1, j); 20 printf(")"); 21 } 22 23 int print_intermedia(int x, int y){ 24 if(x == y)return val[x]; 25 int v = print_intermedia(x, pos[x][y]) + print_intermedia(pos[x][y] + 1, y); 26 printf("%d ", v); 27 return v; 28 } 29 30 int main(int argc, char const *argv[]){ 31 int N; 32 scanf("%d", &N); 33 for(int i = 1; i <= N; ++i){ 34 scanf("%d", &val[i]); 35 } 36 memset(sum, -1, sizeof(sum)); 37 38 for(int i = 1; i <= N; ++i){ 39 dp[i][i] = 0; 40 pos[i][i] = i; 41 sum[i][i]= val[i]; 42 for(int j = i + 1; j <= N; ++j){ 43 sum[i][j] = sum[i][j - 1] + val[j]; 44 } 45 } 46 47 for(int j = 1; j < N; ++j){ 48 for(int i = 1; i + j <= N; ++i){ 49 int opt_v = INT_MAX, opt_p = 0; 50 for(int k = i + j - 1; k >= i; --k){ 51 if(opt_v > dp[i][k] + dp[k + 1][i + j] + sum[i][i + j]){ 52 opt_v = dp[i][k] + dp[k + 1][i + j] + sum[i][i + j]; 53 opt_p = k; 54 } 55 } 56 pos[i][i + j] = opt_p; 57 dp[i][i + j] = opt_v; 58 } 59 } 60 print_path(1, N); 61 printf("\n"); 62 printf("%d\n", dp[1][N]); 63 print_intermedia(1, N); 64 printf("\n"); 65 66 return 0; 67 }