zoukankan      html  css  js  c++  java
  • 就决定是你了!

    题目来源:https://biancheng.love/contest-ng/index.html#/34/problems

    题目描述

    Nova君来到神奇宝贝中心,准备从存储机中挑选若干个Pockmon去挑战最后的四天王和联盟冠军。Nova君现在有N只可挑选的Pockmon,对于第 i 只Pockmon,他的体总为 wi ,战斗力为 vi 。现在联盟规定,只能携带总重量为M的Pockmon进行挑战。那么,Nova君要怎么挑选才能使战斗力最强呢?大家肯定会说,这不是个简单的背包问题嘛?嗯,大概。但是现在有个问题,由于某些Pockmon在冒险的途中,和存储机内的其他Pockmon产生了羁绊,有可能对另一只Pokmon产生依赖,非得被依赖的那只被选中才能发挥战斗力,否则只能是个战斗力为0的卖萌生物而已,好在每只Pockmon都很专情,只会依赖一只(或者不依赖)。

    PS:

    (1) 依赖关系不对称,即,若A依赖B,B不一定依赖A,俗称beitai;

    (2) 可能出现这样的情况:A依赖B,B依赖C,C依赖A,俗称love triangle,当然也有可能是多边形(悲伤脸)

    (3) 保证不会出现自己依赖自己的情况

    输入

    多组测试数据(组数不超过10),对于每组数据,输入4行,第一行是两个正整数N,M,表示Pockmon总数和联盟允许的最大重量,第二行包含N个正整数w1,w2...wn,表示第 i 个Pockmon的重量,第三行包含N个正整数v1,v2...vn,表示第 i 个Pockmon的战斗力,第四行包含N个正整数D1,D2...Dn,表示第 i 个Pockmon依赖的Pockmon的序号,如果没有依赖对象,则 Di=0。

    PS:输入数据都在INT范围内

    输出

    对于每组数据,输出一行,表示战斗力的最大值

    输入样例

    3 10
    4 5 6
    2 3 4
    3 1 2
    3 10
    4 5 6
    2 3 4
    0 1 1
    

    输出样例

    0
    6
    代码:
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int e=505;
      5 int n,m,tmpw=0,tmpn;
      6 int w[e]= {0},v[e]= {0},b[e]= {0},c[e]= {0},f[e][5*e]= {0},d[e]= {0};
      7 bool mapp[e][e]= {0};
      8 
      9 void floride()
     10 {
     11     for(int i=1; i<=n; i++) //弗洛里德判断是否有环;
     12         for(int j=1; j<=n; j++)
     13             for(int k=1; k<=n; k++)
     14                 if(mapp[k][i]==1 && mapp[i][j]==1)
     15                     mapp[k][j]=1;
     16 }
     17 
     18 
     19 void merge()//合点
     20 {
     21     tmpn=n;
     22     for(int i=1; i<=tmpn; i++)
     23         for(int j=1; j<=tmpn; j++)
     24         {
     25             if(mapp[i][j]==1 && mapp[j][i]==1 && i!=j && w[i]>0 && w[j]>0)//如果是新环;
     26             {
     27                 tmpn++;
     28                 v[tmpn]=v[i]+v[j];
     29                 w[tmpn]=w[i]+w[j];
     30                 tmpw--;
     31                 w[i]=tmpw;
     32                 w[j]=tmpw;    //tmpw+tmpn永远等于最开始的n
     33             }
     34 
     35             //如果j依赖的点被合并(是旧环),且j在环里
     36             if(w[d[j]]<0 && w[j]>0 && mapp[j][d[j]]==1 && mapp[j][d[j]]==1)
     37             {
     38                 w[n-w[d[j]]]+=w[j];
     39                 v[n-w[d[j]]]+=v[j];
     40                 w[j]=w[d[j]];
     41             }
     42 
     43             //如果j依赖的点在环里,但是j不在环里
     44             if(w[d[j]]<0 && w[j]>0)
     45                 if((mapp[j][d[j]]==1 && mapp[d[j]][j]==0) || (mapp[j][d[j]]==0 && mapp[d[j]][j]==1))
     46                     d[j]=n-w[d[j]];
     47         }
     48 }
     49 
     50 int  dfs(int x,int k)
     51 {
     52     if(f[x][k]>0)    return(f[x][k]);
     53     if(x==0 || k<=0)    return(0);
     54     //不取x
     55     f[b[x]][k]=dfs(b[x],k);
     56     f[x][k]=f[b[x]][k];
     57     int y=k-w[x];
     58     for(int i=0; i<=y; i++)
     59     {
     60         f[c[x]][y-i]=dfs(c[x],y-i);
     61         f[b[x]][i]=dfs(b[x],i);
     62         f[x][k]=max(f[x][k],v[x]+f[c[x]][y-i]+f[b[x]][i]);
     63     }
     64     return(f[x][k]);
     65 }
     66 
     67 
     68 
     69 int main()
     70 {
     71     while(cin>>n>>m)
     72     {
     73         tmpw=0;
     74         memset(w,0,sizeof(w));
     75         memset(v,0,sizeof(v));
     76         memset(c,0,sizeof(c));
     77         memset(b,0,sizeof(b));
     78         memset(d,0,sizeof(d));
     79         memset(f,0,sizeof(f));
     80         memset(mapp,0,sizeof(mapp));
     81 
     82         for(int i=1; i<=n; i++)
     83             scanf("%d",&w[i]);
     84         for(int i=1; i<=n; i++)
     85             scanf("%d",&v[i]);
     86         for(int i=1; i<=n; i++)
     87         {
     88             int a;
     89             scanf("%d",&a);
     90             d[i]=a;
     91             mapp[a][i]=1;
     92         }
     93 
     94         floride();
     95         merge();
     96 
     97         //多叉转二叉
     98         for(int i=1; i<=tmpn; i++)
     99             if(w[i]>0)
    100             {
    101                 b[i]=c[d[i]];
    102                 c[d[i]]=i;
    103             }
    104         cout<<dfs(c[0],m)<<endl;
    105     }
    106 }
     
  • 相关阅读:
    Vue3使用vue3-video-player
    centos搭建phantomjs
    windows与Linux写入后门
    webService静态调用方法
    Web开发学习笔记(日更)
    docker修改容器绑定端口
    linux下~/.bashrc、/etc/profile、 $PATH环境变量 作用和修改
    docker for windows安装,修改images位置,修改镜像源,查看/var/lib/docker/containers
    hive修改表DDL
    python 高性能异步爬虫线程&线程池
  • 原文地址:https://www.cnblogs.com/zpfbuaa/p/5037570.html
Copyright © 2011-2022 走看看