zoukankan      html  css  js  c++  java
  • [dp uestc oj] G

    G - 邱老师玩游戏

     
    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个城堡所获得的最多宝物的数量。

    树形dp,学了两种建树的方式,保存边集和保存子结点。这题枚举的顺序很重要,当打叶子结点时,dp[leaf][m]=val[n];打非叶子结点时,子节点v分配k个点数,其余子节点分配m-k-1个点数,怎么实现这点呢?如果dp[V][k]等于0,就等效于没有这个结点,因此可以一个一个的算出dp[Vi]。dp[Ui]表U为根结点子节点为1~i结点的树,算出dp[V(i+1)]相当于增加了一个子节点,dp[Ui]就保存新的这棵树的其余子节点的值。因此在代码中j必须逆序枚举,原理类似滚动数组。

    #include<cstdio>
    #include<vector>
    #include<algorithm>
    #include<memory.h>
    const int MX=201;
    
    int dp[MX][MX];
    bool vis[MX];
    int val[MX];
    
    std::vector<int> son[MX];
    
    
    int m;
    void dfs(int u)//打u前剩下m点 结果保存在dp[u][1~m]
    {
      if(vis[u])return;
      dp[u][1]=val[u];
    
      for(int i=0;i<son[u].size();i++)
      {
        int v=son[u][i];
        if(!vis[v])
          dfs(v);
        for(int j=m;j>1;j--)//保证每个结点最多被选一次;
          for(int k=1;k<j;k++)
            dp[u][j]=std::max(dp[u][j],dp[u][j-k]+dp[v][k]);
      }
    }
    
    int main()
    {
      //freopen("Gin.txt","r",stdin);
      int n;
      int a;
      int i;
      while(~scanf("%d%d",&n,&m)&&n)//EOF=-1; ~(-1)=0
      {
        memset(vis,0,sizeof(vis));
        memset(dp,0,sizeof(dp));
        for(i=0;i<=n;i++)
          son[i].clear();
    
        for(i=1;i<=n;i++)
        {
          scanf("%d%d",&a,val+i);
          son[a].push_back(i);
        }
    
        m++;
        dfs(0);
        printf("%d
    ",dp[0][m]);
      }
     //while(1);
      return 0;
    }
  • 相关阅读:
    awk
    django教材
    saltstack的安装过程
    OPENSTACK学习笔记(1)
    5G核心网架构
    内存采集
    分析CPU文件
    环境管理系统
    属性的两种定义方式
    Python 面向对象(初级篇)
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4523609.html
Copyright © 2011-2022 走看看