• AtCoder Regular Contest 070 D


    /**
    题目:D - No Need 
    链接:http://arc070.contest.atcoder.jp/tasks/arc070_b
    题意:给出N个数,从中选出一个子集,若子集和大于等于K,则这是一个Good子集,现在要求这N个数里无用数的个数。
    无用数的定义是:在这个数所属的所有Good子集中,如果把这个数删去后原子集仍然是一个Good子集,它就是一个无用数
    思路:关键点是存在单调性,如果某个数是必须的,那么比他大的数都是必须的;
    证明如下:假设x是必须的,y是比x大的某个数;x是必须的,即x和其他某些数合成的和s加起来为sum>=k,且这个总和sum是满足>=k的情况中最小的和;且s<k;
    如果某些数包含了y,那么把y去掉后,肯定是sum-y<k;所以y是必须的。
    如果某些数不包含y,那么把x去掉后,再加上y,肯定是>=k的,因为y>=x;
    所以存在单调性。
    这样就可以二分+bitset优化判断。(bitset用于求组合数的和)
    */
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<bitset>
    using namespace std;
    const int maxn = 5005;
    const int inf = 0x3f3f3f3f;
    typedef long long ll;
    int a[maxn];
    int n , k;
    int b[maxn];
    bitset<maxn> dp;
    int judge(int x)
    {
        if(a[x]>=k) return 1;
        ///剔除当前数,剩余的数dp一发;存在性判断.
        dp.reset();
        dp[0] = 1;
        for(int i = 0; i < n; i++){
            if(i==x) continue;
            dp|=(dp<<a[i]);
        }
        for(int i = k-1; i >= k-a[x]; i--){
            if(dp[i]){
                return 1;
            }
        }
        return 0;
    }
    int solve()
    {
    
        sort(a,a+n);
        /*
        int lo = -1, hi = n;
        while(hi-lo>1){
            int m = (lo+hi)/2;
            if(judge(m)) hi = m;
            else lo = m;
        }
        return hi;
        */
        int lo = 0, hi = n-1;
        int mas = -1;///这里必须-1,因为我后面+1了,如果不这样的话,结果>=1;
        while(lo<=hi){
            int m = (lo+hi)/2;
            if(judge(m)) hi = m-1;
            else{
                lo = m+1;
                mas = max(mas,m);
            }
        }
        return mas+1;///下标是mas,所以要再加一;
    }
    int main()
    {
        while(scanf("%d%d",&n,&k)==2)
        {
            for(int i = 0; i < n; i++){
                scanf("%d",&a[i]);
            }
            printf("%d
    ",solve());
        }
        return 0;
    }
  • 相关阅读:
    常见算法复杂度解析
    Linux shell脚本根据文件路径信息获取路径和名称
    linux 目录递归替换差异文件
    Linux普通用户具备root用户操作权限
    java线上异常定位工具
    OCR
    国内镜像
    hadoop镜像
    处理Jsp出现乱码问题
    无缝滚动
  • 原文地址:https://www.cnblogs.com/xiaochaoqun/p/6591293.html
Copyright © 2020-2023  润新知