zoukankan      html  css  js  c++  java
  • 树形dp TELE (POJ1155)

    题目链接:http://poj.org/problem?id=1155

    题解:

    懵。。。。

    这题好像就是01背包吧

    我们用f[x][j+k]来表示以x为根的子树,转播j+k个用户时,能获得的利润

    f[x][j+k]=max(f[x][j+k],f[x][j]+f[son][k]-w);(w表示转播需付出的代价);

    我们先处理好所有的f[son][k]然后来更新当前答案;

    程序:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    struct ding{
        int to,l,next;
    }edge[10010];
    int n,m,cnt,head[5000],num[5000],dp[5000][5000],tem[5000];
    void add(int u,int v,int val)
    {
      edge[++cnt].to=v;edge[cnt].l=val;edge[cnt].next=head[u];head[u]=cnt;
    }
    void dfs(int x)
    {
      for (int i=head[x];i;i=edge[i].next)
      {
        int y=edge[i].to,w=edge[i].l;
        dfs(y);
        for (int j=0;j<=num[x];j++) tem[j]=dp[x][j];
    //我们要先备份,因为在更新过程中,使用到的dp[x][j]也会被更新
        for (int j=0;j<=num[x];j++)
         for (int k=0;k<=num[y];k++)
           dp[x][j+k]=max(dp[x][j+k],tem[j]+dp[y][k]-w);
    //更新
        num[x]+=num[y];
    //一个剪枝,有几个叶子节点,我们就没举几个
      }
    }
    int main()
    {
      int k,x,y;
      scanf("%d%d",&n,&m);
      for (int i=1;i<=n-m;i++)
      {
        scanf("%d",&k);
        for (int j=1;j<=k;j++)
        {
          scanf("%d%d",&x,&y);
          add(i,x,y);
        }
      } 
      for (int i=n;i>=1;i--)
       for (int j=1;j<=m;j++)
       dp[i][j]=-210000000;
      for (int i=n-m+1;i<=n;i++) 
      {
        scanf("%d",&dp[i][1]);
    //预处理
        num[i]=1;
      }
      dfs(1);
      for (int i=m;i>=0;i--)
      if (dp[1][i]>=0)
    //如果不亏钱的话
      {
        printf("%d
    ",i);
        break;
      } 
      return 0;
    } 
  • 相关阅读:
    浅谈iOS的SDK与API
    ulua-应用层模块编码
    ErlangRoad_2
    ErlangRoad_1
    Git笔记--git使用基本概念和术语
    小米Pro 15.6 系统重装记录
    Ubuntu14.04安装opencv2.4.13
    ubuntu配置机器学习环境(四) 安装intel MKL
    ubuntu配置机器学习环境(三) opencv 安装
    ubuntu配置机器学习环境(二) cuda 和cudnn 安装
  • 原文地址:https://www.cnblogs.com/2014nhc/p/6625645.html
Copyright © 2011-2022 走看看