• [vijos 1642]班长的任务 [树形dp]


    背景

    十八居士的毕业典礼(1)

    描述

    福州时代中学2009届十班同学毕业了,于是班长PRT开始筹办毕业晚会,但是由于条件有限,可能每个同学不能都去,但每个人都有一个权值,PRT希望来的同学们的权值总和最大。

    十班有一个周密的电话通知网络,它其实就是一棵树,根结点为班长PRT,由她来负责通知她的下线(也就是儿子节点),下线们继续通知自己的下线(不一定每个下线都要通知),任何人都可以不去:”
    为了使权值总和最大,班长想安排一下人,但是人数很多,人脑是难以应付的,所以她找到十八居士,让他编程用电脑解决。

    格式

    输入格式

    输入第一行两个整数n,m表示有n位同学,至多只能去m位同学。(1<=m<=n)
    接下来2*n行,每两行代表一个同学的信息(如果这位同学没有子节点,就只有一行)。

    每个同学的第一行两个整数p,s,表示这位同学权值为p,子节点个数s;(-100<=p<=100)
    第二行s个整数,表示这位同学的子节点的编号。

    班长的编号一定为1。

    对于20%数据1<=n<=10
    对于60%数据1<=n<=100
    对于100%数据1<=n<=1000

    输出格式

    输出一个整数,表示权值的最大值。

    样例

    样例输入1

    8 5
    100 2
    2 3
    79 2
    4 5
    109 3
    6 7 8
    100 0
    100 0
    100 0
    101 0
    108 0

    样例输出1

    518


    My Solution

    id序列树形dp!!!

    神秘!

    const int maxn=1001;
    int d[maxn];               -------->WA!!!!
    
    int d[1001];                -------->AC!!!!

    于是我改成了

    const int maxn=1010;
    int d[maxn];

    AC!!!

    C++基本的东西还要多学

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<vector>
     5 using namespace std;
     6 #define inf 0x3f3f3f3f
     7 
     8 inline int read(){
     9     int re=0;
    10     char ch;
    11     bool flag=0;
    12     while((ch=getchar())!='-'&&(ch<'0'||ch>'9'));
    13     ch=='-'?flag=1:re=ch-'0';
    14     while((ch=getchar())>='0'&&ch<='9')  re=(re<<1)+(re<<3)+ch-'0';
    15     return flag?-re:re;
    16 }
    17 
    18 struct edge{
    19     int to,next;
    20     edge(int to=0,int next=0):
    21         to(to),next(next){}
    22 };
    23 
    24 const int maxn=1010;
    25 
    26 vector<edge> edges;
    27 int n,m;
    28 int head[maxn];
    29 int w[maxn],num[maxn];
    30 int dp[maxn][maxn];
    31 int id[maxn],count[maxn],q=0;
    32 int root=1;
    33 int cnt=0;
    34 int ans=-inf;
    35 
    36 inline void add_edge(int from,int to){
    37     edges.push_back(edge(to,head[from]));
    38     head[from]=++cnt;
    39 }
    40 
    41 void init(){
    42     n=read();  m=read();
    43     edges.push_back(edge(0,0));
    44     for(int i=1;i<=n;i++){
    45         w[i]=read();
    46         num[i]=read();
    47         for(int j=1;j<=num[i];j++){
    48             int to=read();
    49             add_edge(i,to);
    50         }
    51     }
    52 }
    53 
    54 void dfs(int x){
    55     id[++q]=x;
    56     count[x]=1;
    57     for(int ee=head[x];ee;ee=edges[ee].next){
    58         dfs(edges[ee].to);
    59         count[x]+=count[edges[ee].to];
    60     }
    61 }
    62 
    63 void solve(){
    64     memset(dp,-127,sizeof dp);
    65     dfs(root);
    66     for(int i=1;i<=n;i++){
    67         dp[i][0]=0;
    68         dp[i][1]=w[id[i]];
    69     }
    70     for(int i=n-1;i>0;i--)
    71         for(int j=1;j<=m;j++)
    72             dp[i][j]=max(dp[i+1][j-1]+w[id[i]],dp[i+count[id[i]]][j]);
    73     for(int i=1;i<=m;i++)
    74         ans=max(ans,dp[1][i]);
    75     printf("%d
    ",max(ans,0));
    76 }
    77 
    78 int main(){
    79     //freopen("temp.in","r",stdin);
    80     init();
    81     solve();
    82     return 0;
    83 }

     于是他走了  就像他没有来过一样

     
  • 相关阅读:
    cmd中编译java
    java出错
    去掉开始菜单中新装程序的红色标记【Windows】
    Windows安装java
    看视频缓冲好还一卡一卡【解决】
    python图像卷积
    电脑硬盘、内存
    python 查询Neo4j多节点的多层关系
    python 快速排序实现
    python 二分法实现
  • 原文地址:https://www.cnblogs.com/ZYBGMZL/p/6882676.html
Copyright © 2020-2023  润新知