zoukankan      html  css  js  c++  java
  • TTTTTTTTTTTTT CDOJ 1136 邱老师玩游戏 树形dp

    邱老师玩游戏

    Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
     

    邱老师最近在玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中邱老师允许攻克M个城堡并获得里面的宝物。

    但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡。你能帮邱老师算出要获得尽量多的宝物应该攻克哪M个城堡吗?

    Input

    每个测试实例首先包括2个整数,N,M.(1 <= M <= N <= 200);

    在接下来的N行里,每行包括2个整数,a,b.

    在第 i 行,a 代表要攻克第 i 个城堡必须先攻克第 a 个城堡,如果 a = 0 则代表可以直接攻克第 i 个城堡。b 代表第 i 个城堡的宝物数量, b >= 0。

    当N = 0, M = 0输入结束。

    Output

    对于每个测试实例,输出一个整数,代表邱老师攻克M个城堡所获得的最多宝物的数量。

    Sample input and output

    Sample InputSample Output
    3 2
    0 1
    0 2
    0 3
    7 4
    2 2
    0 1
    0 4
    2 1
    7 1
    7 6
    2 2
    0 0
    5
    13 

    Source

    2015 UESTC Training for Dynamic Programming
     
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <map>
    #include <algorithm>
    #include <set>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long Ull;
    #define MM(a,b) memset(a,b,sizeof(a));
    const double eps = 1e-10;
    const int  inf =0x7f7f7f7f;
    const double pi=acos(-1);
    const int N=205;
    int n,m,dp[N][N],vlue[N];
    vector<int> G[N];
    
    void dfs(int u)
    {
       dp[u][0]=0;
       dp[u][1]=vlue[u];
       for(int i=0;i<G[u].size();i++)
       {
           int v=G[u][i];
           dfs(v);
           for(int j=m;j>=2;j--)
              for(int k=1;k<j;k++)
                 dp[u][j]=max(dp[u][j],dp[v][k]+dp[u][j-k]);
       }
    }
    
    int main()
    {
        while(~scanf("%d%d",&n,&m)&&(n||m))
        {
            m++;
            MM(dp,0);
            for(int i=0;i<=n;i++) G[i].clear();
            for(int i=1;i<=n;i++)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                G[a].push_back(i);
                vlue[i]=b;
            }
            dfs(0);
            printf("%d
    ",dp[0][m]);
        }
        return 0;
    }
    

      分析:这道题必须要dfs是因为涉及到树的搜索,

    设dp[u][j]表示以u为根的子树在选取点的个数至多为j个时能得到的最大权值;

    那么接下来枚举下他的每个子节点就好了,转一下状态就好了

  • 相关阅读:
    类加载器
    java类的主动使用方式
    Java类装载器和命名空间
    cas改造
    所有jar文件列出工具
    源码阅读工具_解析所有类的使用情况
    web(s,哈哈,w,没有,d,用处,f)web框架引用类的次数
    struts2类型转换器StrutsTypeConverter的使用
    struts2的验证框架的使用和扩展
    Python3连接MySQL
  • 原文地址:https://www.cnblogs.com/smilesundream/p/5768152.html
Copyright © 2011-2022 走看看