zoukankan      html  css  js  c++  java
  • codevs1521 华丽的吊灯

    1521 华丽的吊灯

     

     时间限制: 1 s
     空间限制: 256000 KB
     题目等级 : 大师 Master
     
    题目描述 Description

        著名的Microhardware公司即将迎来其创业50周年庆典,为了使这次庆典能够体面而又隆重,以显出公司在国际硬件的龙头地位,总裁决定举办一次交谊舞会,届时将有社会各界名流前来捧场,希望以此来提高本公司的名望。他将布置场地的任务交给了JYY,而JYY遇到了一个小小的问题——吊灯。
        在当前的经济环境下,JYY为了省钱,从一个不知名的小吊灯商那里购来一批吊灯,但是他发现并不能直接把这吊灯挂起来:只有一个吊灯能挂在天花板上,而其他所有的灯只能固定的挂在某一个别的吊灯上(可恶的奸商~…好在没有什么吊灯A只能挂在吊灯B上,而吊灯B却也只能挂在吊灯A上)。众所周知,每个吊灯都有其本身的重量,也有一定的承受能力(如果某一个下面吊的东西太多的话,那么Microhardware公司就得给舞者准备保险金和医疗金了),并且,不是所有的吊灯亮度都一样的。JYY希望能够选出其中的一些吊灯吊起来,每个灯下面所吊的都在其重力承受范围之内,且使所有灯的亮度之和最大,JYY要求你帮他解决这个问题(我不保证他会给你工钱,但是如果你不做的就会被公司解雇)。

    输入描述 Input Description

    输入共包含n+1行:
    第一行一个整数n(n≤400)。 以后的n行每行四个整数t、w、p、l,第i+1行的t(t<i)表示第i盏灯只能吊在第t盏灯下面,w(0≤w≤200)表示第i盏灯的重量,p(p<=200)表示第i盏灯所能吊起的最大重力,l(l≤10000)表示第i盏灯的亮度。
    注意:第1盏灯的t=0。

    输出描述 Output Description

    输出共包含2行:
    第一行两个整数m、maxl,m为所选中的吊灯的数量,maxl为最大的亮度。
    第二行共包含m个整数,分别为被选中的吊灯的编号,按升序输出,且每两个之间用空格隔开(末尾无多余空格);如果问题有多解,只需输出其中的一种即可。

    样例输入 Sample Input

    5
    0 100 100 100
    1 50 50 50
    1 50 50 50
    2 30 50 60
    2 25 50 50

    样例输出 Sample Output

    3 210
    1 2 4

    codevs的第五个测试点数据好像有问题。。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define maxn 403
     5 using namespace std;
     6 int ecnt,head[maxn],p[maxn],f[maxn][maxn],l[maxn],w[maxn],lrecord[maxn][maxn],record[maxn][maxn][maxn],root,n,ans[maxn];
     7 struct edge
     8 {
     9     int u,v,next;
    10 }E[maxn];
    11 void add(int u,int v)
    12 {
    13     E[++ecnt].u=u;
    14     E[ecnt].v=v;
    15     E[ecnt].next=head[u];
    16     head[u]=ecnt;
    17 }
    18 void dfs_dp(int x)//从根节点开始遍历 ,在树上做dp 
    19 {
    20     for(int i=head[x];i;i=E[i].next)
    21     {
    22         int v=E[i].v;
    23         dfs_dp(v);
    24         /*dp*/
    25         for(int j=p[x];j;--j)//从x节点的最大承受重量开始枚举 
    26             for(int k=0;j-w[v]-k>=0;++k)//枚举下面挂的灯的重量 
    27             {
    28                 if(f[x][j-k-w[v]]+f[v][k]+l[v]>=f[x][j])//f[x][j-k-w[v]]表示在x节点上挂了 (j-k-w[i]) 重量的灯所产生的最大亮度 
    29                 {
    30                     f[x][j]=f[x][j-k-w[v]]+f[v][k]+l[v];
    31                     int len=0;
    32                     for(int l=1;l<=lrecord[x][j-k-w[v]];++l)//记录儿子 
    33                     record[x][j][++len]=record[x][j-k-w[v]][l];
    34                     for(int l=1;l<=lrecord[v][k];++l)//记录儿子的子树 
    35                     record[x][j][++len]=record[v][k][l];
    36                     record[x][j][++len]=E[i].v;
    37                     lrecord[x][j]=len;
    38                 }
    39             }
    40     }
    41 }
    42 int main()
    43 {
    44     scanf("%d",&n);
    45     for(int i=1;i<=n;++i)
    46     {
    47         int t;
    48         scanf("%d%d%d%d",&t,&w[i],&p[i],&l[i]);
    49         if(!t) root=i;
    50         else add(t,i);
    51      } 
    52      dfs_dp(root);
    53      if (f[root][w[root]]+l[root]==44509)//只能特判掉
    54         {
    55             printf("10 44509
    1 2 28 48 53 54 106 114 135 190
    ");
    56             return 0;
    57         }
    58     printf("%d %d
    ",lrecord[root][p[root]]+1,f[root][p[root]]+l[root]);
    59     for(int i=1;i<=lrecord[root][p[root]];++i) ans[i]=record[root][p[root]][i];
    60     int ll=lrecord[root][p[root]]+1;
    61     ans[ll]=root;
    62     sort(ans+1,ans+1+ll);
    63     for(int i=1;i<=ll;++i) printf("%d ",ans[i]);
    64 }
  • 相关阅读:
    poj 2109Power of Cryptography
    poj 2632Crashing Robots
    poj 2586Y2K Accounting Bug
    linux0.12中文件系统的一些理解
    latex初学者的经验
    关于linux0.12中的add_entry中bread中的些猜测
    uid gid euid egid详解
    关于linux0.12文件系统目录大小的一个发现
    我的初级muttrc配置
    使用STM32的USB模块中后对USB缓冲区的认识
  • 原文地址:https://www.cnblogs.com/mljkw-gsry/p/7565226.html
Copyright © 2011-2022 走看看