noip2003 加分二叉树 dp
2016-11-02 14:24
387 查看
中序遍历中,一个节点子树是该点向左右扩展连续的一段。dp[x][l][r]是记录以x为根,l,r为左右端点的子树所产生的最大价值。记忆化搜索做。
#include<bits/stdc++.h> #define LL long long using namespace std; LL dp[35][35][35]; LL a[35]; int ch[35][35][35][2]; LL dfs(int x,int l,int r) { if(dp[x][l][r]) return dp[x][l][r]; LL L=0,R=0; if(l==x)L=1; else { for(int i=l;i<x;i++) { LL p=dfs(i,l,x-1); if(L<p) {L=p;ch[x][l][r][0]=i;} } } if(r==x) R=1; else { for(int i=x+1;i<=r;i++) { LL p=dfs(i,x+1,r); if(R<p) {R=p;ch[x][l][r][1]=i;} } } dp[x][l][r]=L*R+a[x]; if(l==r) dp[x][l][r]--; return dp[x][l][r]; } int root; void dfs2(int x,int l,int r) { if(!x) return ; printf("%d ",x); dfs2(ch[x][l][r][0],l,x-1); dfs2(ch[x][l][r][1],x+1,r); } int main() { int n;scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); LL ans=0; for(int i=1;i<=n;i++) { LL p=dfs(i,1,n); if(ans<p) { ans=p; root=i; } } printf("%d\n",ans); dfs2(root,1,n); return 0; }
相关文章推荐
- 【树形DP】[NOIP2003]加分二叉树
- NOIP2003-加分二叉树-dp-区间型动态规划
- Noip 2003 加分二叉树 - 区间DP
- ACM 106. [NOIP2003] 加分二叉树(区间dp)
- [NOIP2003]区间dp-加分二叉树
- 计蒜客区间dp例题 奇怪的二叉树(NOIP2003加分二叉树)
- [NOIP 2003] 加分二叉树:DP
- NOIP2003提高组 加分二叉树
- 【NOIP2003】加分二叉树题解
- noip2003加分二叉树 2008.10.30
- 洛谷 P1040 [NOIP2003 T3] 加分二叉树
- noip2003 加分二叉树 (树形dp+分治法,已知中序,输出前序)
- 洛谷P1040 加分二叉树(NOIP2003)
- [NOIP2003]加分二叉树
- NOIP2003 加分二叉树
- CJOJ 1010【NOIP2003】加分二叉树 / Luogu 1040 加分二叉树 /CodeVS 1090 加分二叉树
- NOIP 2003 加分二叉树
- [noip2003]加分二叉树
- NOIP2003 加分二叉树
- Noip 2003 加分二叉树