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 }

 

你可能感兴趣的:(OS)