博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
sjtu 1077 加分二叉树
阅读量:6810 次
发布时间:2019-06-26

本文共 1371 字,大约阅读时间需要 4 分钟。

树型DP入门题

题目链接:http://acm.sjtu.edu.cn/OnlineJudge/problem/1077

•设f(i,j)中序遍历为i,i+1,…,j的二叉树的最大加分,则有:

  f(i,j)=max{f[i,k-1]*f[k+1,j] +d[k]}

•显然 f(i,i)=d[i]
•答案为f(1,n)
•1<=i<=k=<=j<=n
•时间复杂度  O(n3)
•要构造这个树,只需记录每次的决策值,令b(i,j)=k,表示中序遍历为i,i+1,…,j的二叉树的取最优决策时的根结点为k

最后前序遍历这个树即可。

 

/*树型DP*/#include 
#include
#include
using namespace std;#define MAX 35#define INF 0x3f3f3f3flong long dp[MAX][MAX];int p[MAX][MAX];int a[MAX];queue
q;long long dfs(int i ,int j){ if(i>j) return dp[i][j]=1; if(dp[i][j]!=-1) return dp[i][j]; dp[i][j]=-INF; for(int k=i; k<=j; k++) { long long t1=dfs(i,k-1); long long t2=dfs(k+1,j); if(t1*t2+a[k] > dp[i][j]) { dp[i][j]=t1*t2+a[k]; p[i][j]=k; } } return dp[i][j];}void travel(int i ,int j){ if(i>j) return ; if(i==j) { q.push(i); return ; } int k=p[i][j]; q.push(k); travel(i,k-1); travel(k+1,j);}int main(){ int n; while(scanf("%d",&n)!=EOF) { for(int i=1; i<=n; i++) scanf("%d",&a[i]); memset(p,-1,sizeof(p)); memset(dp,-1,sizeof(dp)); for(int i=1; i<=n; i++) { dp[i][i]=a[i]; p[i][i]=i; } dfs(1,n); printf("%lld\n",dp[1][n]); while(!q.empty()) q.pop(); travel(1,n); printf("%d",q.front()); q.pop(); while(!q.empty()) { printf(" %d",q.front()); q.pop(); } printf("\n"); } return 0;}

 

转载地址:http://zswzl.baihongyu.com/

你可能感兴趣的文章
Linux 获取设备树源文件(DTS)里描述的资源【转】
查看>>
Effective C++ 阅读笔记(二)public继承与继承中的函数覆盖
查看>>
什么是UV?
查看>>
Docker 容器测试全探索
查看>>
如何在Ubuntu 16.04中创建GIF动图
查看>>
结构和类的区别
查看>>
Stringbuffer与Stringbuilder源码学习和对比
查看>>
AgileEAS.NET平台开发Step By Step系列-药店系统-索引
查看>>
黑盒测试难还是白盒测试难?
查看>>
jQuery CSS 函数
查看>>
Stanford coursera Andrew Ng 机器学习课程编程作业(Exercise 2)及总结
查看>>
字符输出流Writer简要概括
查看>>
ASP.NET MVC5+EF6+EasyUI 后台管理系统(53)-工作流设计-我的批阅
查看>>
Centos 学习大纲
查看>>
我们前端跟后端是怎么合作的
查看>>
我的第一个Chrome扩展
查看>>
线偏移处理参数说明
查看>>
Web Services Introduction
查看>>
快速排序算法之所有版本的c/c++实现
查看>>
linux进程的休眠(等待队列)【转】
查看>>