zoukankan      html  css  js  c++  java
  • vijos1642 班长的任务

    背景
    十八居士的毕业典礼(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

    做后感:这题挂了……挂了一个小时没调出来,就不做了……

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    int n,m;
    int tot=0;
    int f[1001][1001];
    int w[1001];
    struct node{
        int l,r;
    }a[1001];
    
    int read()
    {
        char ch=getchar();
        while (ch<'0' || ch>'9') ch=getchar();
        int x=0;
        while (ch>='0' && ch<='9') { x=x*10+ch-'0'; ch=getchar();    }
        return x;
    }
    
    void insert(int x,int y)//左儿子右兄弟,多叉转二叉 
    {
        if (a[x].l==0) a[x].l=y;
          else 
          {
              int p=a[x].l;
              while (a[p].r!=0) p=a[p].r;
              a[p].r=y;
          }
        return;
    }
    
    void dp(int k,int m)
    {
        if (k==0 || m==0) { f[k][m]=0; return; }
        if (f[k][m]!=-1) return;
        dp(a[k].r,m);
        f[k][m]=f[a[k].r][m];
        for (int i=0; i<m; i++)
        {
            dp(a[k].l,i); dp(a[k].r,m-i-1);
            f[k][m]=max(f[k][m],f[a[k].l][i]+f[a[k].r][m-i-1]+w[k]); 
        } 
        return;
    }
    
    int main()
    {
        n=read(); m=read();
        for (int i=1; i<=n; i++)
        {
            w[i]=read(); int q=read();
            for (int j=1; j<=q; j++)
            {
                int t=read();
                insert(i,t);
            }
        }
        memset(f,-1,sizeof(f));
        dp(1,m);
        cout << f[1][m] << endl;
        return 0;
    }

     看了看黄学长做的,感觉整个人都升华了……学长用的是N*M的算法,太高大上了。写了写注释,发一发。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n,m; int v[1001],s[1001],a[1001][1001]; int f[1001][1001]; int list[1001],count[1001],q; int tree_traversal(int k) { list[++q]=k; if (s[k]==0) {return ++count[k];} for (int i=1; i<=s[k]; i++) count[k]+=tree_traversal(a[k][i]); return ++count[k]; } int main() { memset(f,-127,sizeof(f)); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { int t; scanf("%d%d",&v[i],&t); while(t--) scanf("%d",&a[i][++s[i]]); } tree_traversal(1);//把树转化成一个序列 for(int i=1; i<=n; i++) { f[i][0]=0; f[i][1]=v[list[i]]; }//f[i][j]表示第i个位置上的人通知j个人能得到的最大权值 for(int i=n-1;i>=0;i--) for(int j=1;j<=m;j++)   f[i][j]=max(f[i+1][j-1]+v[list[i]],f[i+count[list[i]]][j]); int ans=-999999; for (int i=1; i<=m; i++) ans=max(ans,f[1][i]); printf("%d",max(ans,0)); return 0; }
  • 相关阅读:
    nginx-1.8.1的安装
    ElasticSearch 在3节点集群的启动
    The type java.lang.CharSequence cannot be resolved. It is indirectly referenced from required .class files
    sqoop导入导出对mysql再带数据库test能跑通用户自己建立的数据库则不行
    LeetCode 501. Find Mode in Binary Search Tree (找到二叉搜索树的众数)
    LeetCode 437. Path Sum III (路径之和之三)
    LeetCode 404. Sum of Left Leaves (左子叶之和)
    LeetCode 257. Binary Tree Paths (二叉树路径)
    LeetCode Questions List (LeetCode 问题列表)- Java Solutions
    LeetCode 561. Array Partition I (数组分隔之一)
  • 原文地址:https://www.cnblogs.com/Shymuel/p/4393652.html
Copyright © 2011-2022 走看看