Vijos 1100 加分二叉树(树形DP)

题目链接

感觉和区间DP很类似,觉得还挺简单的,难得1Y,以前的时候直接没思路。。。

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <queue>

 4 #include <string>

 5 using namespace std;

 6 #define LL long long

 7 int p[101];

 8 int o[101];

 9 LL dp[101][101];

10 int num = 1;

11 LL dfs(int L,int R)

12 {

13     int i;

14     LL temp;

15     LL maxz = -1000000;

16     if(dp[L][R])

17     return dp[L][R];

18     if(L > R)

19     return 1;

20     if(L == R)

21     return p[L];

22     for(i = L;i <= R;i ++)

23     {

24         if(maxz < (temp = dfs(L,i-1)*dfs(i+1,R)+p[i]))

25         {

26             maxz = temp;

27         }

28     }

29     dp[L][R] = maxz;

30     return dp[L][R];

31 }

32 void find(int L,int R)

33 {

34     int i,key;

35     if(L == R)

36     {

37         o[num++] = L;

38         return ;

39     }

40     else if(L > R)

41     return ;

42     for(i = L;i <= R;i ++)

43     {

44         if(dp[L][R] ==  dfs(L,i-1)*dfs(i+1,R)+p[i])

45         {

46             key = i;

47             break;

48         }

49     }

50     o[num++] = key;

51     find(L,key-1);

52     find(key+1,R);

53 }

54 int main()

55 {

56     int i,n;

57     scanf("%d",&n);

58     for(i = 1;i <= n;i ++)

59     scanf("%d",&p[i]);

60     printf("%lld\n",dfs(1,n));

61     find(1,n);

62     for(i = 1;i <= n;i ++)

63     {

64         if(i == 1)

65         printf("%d",o[i]);

66         else

67         printf(" %d",o[i]);

68     }

69     printf("\n");

70     return 0;

71 }

 

你可能感兴趣的:(二叉树)