P1270 “访问”美术馆

  一道树形dp啦~~~

  其实我是做过这道题的加强版后才做的这道题……不过先由浅入深,先发这个~

  首先,我定义 f [ u ] [ i ] 为在第 u 个点上,给它时间为 i 是能获取的最大价值。

  有一个需要注意,如果说这是一个展厅,设给这个点的时间为 t ,那么实际能偷画的时间只有 t - 双倍边权。

  这也导致了如果这个点是一个分支,那么我给两边的时间和(就是我给这个点的时间)必定要大于等于二倍边权。

  这样就避免了在dfs里传入无关的冗杂的变量,使得状态统一比较容易维护。

  接下来贴代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
#define maxn 2000
int f[2000][2000],n,am=1;
void dfs(int x)
{
    int t,num;
    scanf("%d%d",&t,&num);
    t*=2;
    if(num)
    {
        for(int i=5+t;i<=100+t;i++)
        f[x][i]=min((i-t)/5,num);
        return ;
    }
    int l=++am;
    dfs(l);
    int r=++am;
    dfs(r);
    for(int i=t;i<=n;i++)
    for(int j=0;j<=i-t;j++)
    f[x][i]=max(f[x][i],f[l][j]+f[r][i-t-j]);
}
int main()
{
    scanf("%d",&n);
    n--;
    dfs(1);
    printf("%d",f[1][n]);
    return 0;
}
原文地址:https://www.cnblogs.com/popo-black-cat/p/10325018.html