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

    题目描述

    老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一部分没有,同学们就会抗议。所以老师想请你帮他求出他该选多少学霸,才能既不让同学们抗议,又与原来的M尽可能接近

    输入输出格式

    输入格式:

    第一行,三个正整数N,M,K。

    第2...K行,每行2个数,表示一对实力相当的人的编号(编号为1…N)

    输出格式:

    一行,表示既不让同学们抗议,又与原来的M尽可能接近的选出学霸的数目。(如果有两种方案与M的差的绝对值相等,选较小的一种:)

    输入输出样例

    输入样例#1:
    4 3 2
    1 2
    3 4
    输出样例#1: 
    2

    说明

    100%的数据N,P<=20000

    闲话:

    学霸还用选吗,显然是我啊。。。

    分析:

    本题先用并查集将实力相同的合并,然后再按背包DP做就行了。

    CODE:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cmath>
     4 #include <iostream>
     5 #include <algorithm>
     6 using namespace std;
     7 const int M=100005;
     8 int n,m,k,fa[M],cnt[M],f[M];
     9 int read(){
    10     char c=getchar();int ans=0;
    11     while (c<'0'||c>'9') c=getchar();
    12     while (c>='0'&&c<='9') ans=(ans<<1)+(ans<<3)+(c^48),c=getchar();
    13     return ans;
    14 }
    15 int found(int x){
    16     if (fa[x]==x) return x;
    17     return fa[x]=found(fa[x]);
    18 }
    19 int main(){
    20     n=read(),m=read(),k=read();
    21     for (int i=1;i<=n;i++) fa[i]=i;
    22     for (int i=1,x,y;i<=k;i++){
    23         x=read(),y=read();
    24         fa[found(x)]=found(y);
    25     }
    26     for (int i=1;i<=n;i++) cnt[found(i)]++;
    27     f[0]=1;
    28     for (int i=1;i<=n;i++){
    29         if (!cnt[i]) continue;
    30         for (int j=n;j>=cnt[i];j--) f[j]|=f[j-cnt[i]];
    31     }
    32     int key=1000000,ans=1000000;
    33     for (int i=0;i<=n;i++)
    34         if (f[i]&&abs(i-m)<ans) ans=abs(i-m),key=i;
    35     printf("%d",key);
    36     return 0;
    37 }
  • 相关阅读:
    二维数组的使用及其内存结构
    一维数组的练习
    数组的默认初始化
    数组
    完数
    break与continue
    乘法表及质数的输出法
    嵌套循环的使用
    Elasticsearch索引和查询性能调优
    elasticsearch数据冷热分离、数据冷备
  • 原文地址:https://www.cnblogs.com/kanchuang/p/11150471.html
Copyright © 2011-2022 走看看