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

本文共 1470 字,大约阅读时间需要 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;}

 

转载于:https://www.cnblogs.com/scau20110726/archive/2013/03/18/2966640.html

你可能感兴趣的文章
miniWindbg 功能
查看>>
CF772E Verifying Kingdom
查看>>
测试驱动开发
查看>>
轻松实现远程批量拷贝文件脚本(女学生作品)
查看>>
【沟通之道】头脑风暴-女人的心思你别猜
查看>>
Windows Phone 8 开发资源汇总
查看>>
Git:配置
查看>>
神经系统知识普及
查看>>
Spring可扩展Schema标签
查看>>
c++ STL unique , unique_copy函数
查看>>
http://miicaa.yopwork.com/help/overall/
查看>>
浅谈关于特征选择算法与Relief的实现
查看>>
mybatis-spring 项目简介
查看>>
Wireshark抓取RTP包,还原语音
查看>>
Behavioral模式之Memento模式
查看>>
Work Management Service application in SharePoint 2016
查看>>
Dos 改动IP 地址
查看>>
Laravel 源码解读:php artisan make:auth
查看>>
【转】ionic run android 成功launch success,但是genymotion虚拟机没有显示
查看>>
苹果在GitHub上正式开源iOS内核源码
查看>>