您的位置:首页 > 其它

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

2013-03-10 18:53 267 查看
题目链接

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

#include <cstdio>
#include <cstring>
#include <queue>
#include <string>
using namespace std;
#define LL long long
int p[101];
int o[101];
LL dp[101][101];
int num = 1;
LL dfs(int L,int R)
{
int i;
LL temp;
LL maxz = -1000000;
if(dp[L][R])
return dp[L][R];
if(L > R)
return 1;
if(L == R)
return p[L];
for(i = L;i <= R;i ++)
{
if(maxz < (temp = dfs(L,i-1)*dfs(i+1,R)+p[i]))
{
maxz = temp;
}
}
dp[L][R] = maxz;
return dp[L][R];
}
void find(int L,int R)
{
int i,key;
if(L == R)
{
o[num++] = L;
return ;
}
else if(L > R)
return ;
for(i = L;i <= R;i ++)
{
if(dp[L][R] ==  dfs(L,i-1)*dfs(i+1,R)+p[i])
{
key = i;
break;
}
}
o[num++] = key;
find(L,key-1);
find(key+1,R);
}
int main()
{
int i,n;
scanf("%d",&n);
for(i = 1;i <= n;i ++)
scanf("%d",&p[i]);
printf("%lld\n",dfs(1,n));
find(1,n);
for(i = 1;i <= n;i ++)
{
if(i == 1)
printf("%d",o[i]);
else
printf(" %d",o[i]);
}
printf("\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: