• hdu 1561树形dp


    有一点难度的树形dp,只不过数据量不是很大,应该不会出现超内存和超时的问题

    dp[i][j]表示以i为根的树中选j个城堡,注意此时父节点i必须要选取了

    f[i][j]用于临时储存状态,有点像条件背包,树形dp的题想想基本都差不多,和背包都很像,其实做多了dp,也会发现,dp也都一个样

    View Code
     1 #include<iostream>
    2 #include<cstring>
    3 #include<cstdio>
    4 #include<vector>
    5 #define city 205
    6 using namespace std;
    7 vector<int> tree[city];
    8 int dp[city][city];
    9 int f[city][city];
    10 int used[city];
    11 int value[city];
    12 int max(int a,int b)
    13 {
    14 return a>b?a:b;
    15 }
    16 int n,m;
    17 void init()
    18 {
    19 int i;
    20 for(i=0;i<205;i++)
    21 tree[i].clear();
    22 }
    23 void dfs(int x)
    24 {
    25 used[x]=1;
    26 int i,j,k;
    27 dp[x][0]=0;
    28 f[x][0]=0;
    29 int t=tree[x].size();
    30 for(i=0;i<t;i++)
    31 {
    32 int temp=tree[x][i];
    33 if(!used[temp])
    34 dfs(temp);
    35 for(j=m;j>=0;j--)
    36 {
    37 for(k=0;k<=m;k++)
    38 if(dp[temp][k]!=-1&&f[x][j-k]!=-1&&j>=k)
    39 f[x][j]=max(f[x][j],f[x][j-k]+dp[temp][k]);
    40 }
    41 }
    42 for(j=1;j<=m+1;j++)
    43 if(f[x][j-1]!=-1)//判断状态是否可达
    44 dp[x][j]=f[x][j-1]+value[x];
    45 }
    46
    47 int main()
    48 {
    49 int i;
    50 int a,b;
    51 while(scanf("%d%d",&n,&m)&&(m||n))
    52 {
    53 memset(dp,-1,sizeof(dp));
    54 memset(used,0,sizeof(used));
    55 memset(f,-1,sizeof(f));
    56 init();
    57 for(i=1;i<=n;i++)
    58 {
    59 scanf("%d%d",&a,&b);
    60 tree[a].push_back(i);
    61 value[i]=b;
    62 }
    63 value[0]=0;
    64 dfs(0);
    65 printf("%d\n",dp[0][m+1]);
    66 }
    67 return 0;
    68 }
  • 相关阅读:
    苹果远程推送测试
    iOS 模糊化效果 ANBlurredImageView的使用
    VS2015中正确添加GIF的方式
    十大经典排序算法
    Windows Error Code(windows错误代码详解)
    C++捕获系统异常(VS2015设置)
    Qt5 error LNK2019 无法解析的外部符号的解决办法
    Linux常用命令大全(非常全!!!)
    利用MFC Picture Control控件 加载bmp,png
    在C++中如何实现文件的读写
  • 原文地址:https://www.cnblogs.com/caozhenhai/p/2432677.html
Copyright © 2020-2023  润新知