选课 树型DP
题目
题解
无需建树的办法:
选课_树型DP
fi,j=Max(fi,a+fk,b),j=a+b
fi,j
表示以
i
为根的子树,选
类似于深搜,自顶向下,每次递归前将父亲 fr,j 传递给孩子,最后再向上推选出最优解
#include <iostream>
#include <cstring>
using namespace std;
int m, n, f[206][206];
int prev[206], val[206];
void TreeDP(int r, int c)
{
if(c)
for(int i = 1; i <= m; ++i)
if(prev[i] == r)
{
for(int j = 0; j < c; ++j)
f[i][j] = f[r][j] + val[i];
TreeDP(i, c-1);
for(int j = 1; j <= c; ++j)
f[r][j] = max(f[r][j], f[i][j-1]);
}
}
void Solve()
{
memset(f, 0, sizeof(f));
for(int i = 0; i <= n; ++i)
f[0][i] = 0;
TreeDP(0, n);
for(int i = 0; i <= m; ++i)
{
for(int j = 0; j <= n; ++j)
cout<<f[i][j]<<' ';
cout<<endl;
}
cout<<f[0][n]<<endl;
}
int main()
{
while(cin>>m>>n)
{
for(int i = 1; i <= m; ++i)
cin>>prev[i]>>val[i];
Solve();
}
return 0;
}
建树
左孩子右兄弟法则
选课_树转二叉树
总结
对于树型DP,同意建立好的树型结构是有助于建立状态转移方程,大大降低了逻辑上的思考难度,对于树型结构的薄弱还要加强,本质上说,树型DP的孱弱来自于树型数据结构的陌生。