zoukankan      html  css  js  c++  java
  • 选学霸

    题目描述
    老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一部分没有,同学们就会抗议。所以老师想请你帮他求出他该选多少学霸,才能既不让同学们抗议,又与原来的M尽可能接近
    输入输出格式
    输入格式:
    第一行,三个正整数N,M,K。
    第2...K行,每行2个数,表示一对实力相当的人的编号(编号为1…N)
    输出格式:
    一行,表示既不让同学们抗议,又与原来的M尽可能接近的选出学霸的数目。(如果有两种方案与M的差的绝对值相等,选较小的一种:)
    输入输出样例
    输入样例#14 3 2
    1 2
    3 4
    输出样例#12
    说明
    100%的数据N,P<=20000
    题面

     解:

    根据题意可得,对于实力相当的一群人,要么不选,要么都选
    我们就把这一群人看成一个物品,
    跑一边背包,体积范围为 0->m*2
    然后枚举所有体积,找到最合适的答案

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int N=2e4+20;
     5 int n,f[N],size[N];
     6 int F(int x)
     7 {
     8     if(x==f[x]) return x;
     9     else return f[x]=F(f[x]);
    10 }
    11 int m,k,a[N],v[N];
    12 int main()
    13 {
    14     scanf("%d%d%d",&n,&m,&k);
    15     for(int i=1;i<=n;++i) f[i]=i;
    16     for(int i=1,x,y;i<=k;++i)
    17     {
    18         scanf("%d%d",&x,&y);
    19         x=F(x);y=F(y);
    20         f[x]=f[y]=min(x,y);
    21     }
    22     for(int i=1,fa;i<=n;++i)
    23     {
    24         fa=F(i);size[fa]++;
    25         if(!v[fa]) v[fa]=1,a[++a[0]]=fa;
    26     }
    27     memset(f,0,sizeof(f));
    28     for(int i=1;i<=a[0];++i)
    29      for(int j=m*2;j>=size[a[i]];--j)
    30       f[j]=max(f[j],f[j-size[a[i]]]+size[a[i]]);
    31     v[0]=0;
    32     for(int j=0;j<=m*2;++j)
    33      if(abs(v[0]-m)>abs(f[j]-m)) v[0]=f[j];
    34      else if(abs(v[0]-m)==abs(f[j]-m)) v[0]=min(v[0],f[j]);
    35     cout<<v[0];
    36     return 0;
    37 }
    代码
  • 相关阅读:
    springboot 之JPA
    Oracle数据库安装
    Pytho之Django
    springboot之docker化
    opencv之dlib库人脸识别
    opencv之调用摄像头
    springboot之多模块化项目打包
    python学习笔记2--list
    ETL测试
    Mockserver -MOCO的使用
  • 原文地址:https://www.cnblogs.com/adelalove/p/8696354.html
Copyright © 2011-2022 走看看