zoukankan      html  css  js  c++  java
  • Wannafly挑战赛6 锁

    链接:https://ac.nowcoder.com/acm/problem/14732
    来源:牛客网

    题目描述

    106号房间共有n名居民, 他们每人有一个重要度。房间的门上可以装若干把锁。假设共有k把锁,命名为1到k。每把锁有一种对应的钥匙,也用1到k表示。钥匙可以复制并发给任意多个居民。每个106房间的居民持有若干钥匙,也就是1到k的一个子集。如果几名居民的钥匙的并集是1到k,即他们拥有全部锁的对应钥匙,他们都在场时就能打开房门。新的陆战协定规定,一组居民都在场时能打开房门当且仅当他们的重要度加起来至少为m。问至少需要给106号房间装多少把锁。即,求最小的k,使得可以适当地给居民们每人若干钥匙(即一个1到k的子集),使得任意重要度之和小于m的居民集合持有的钥匙的并集不是1到k,而任意重要度之和大于等于m的居民集合持有的钥匙的并集是1到k。

    输入描述:

    第一行两个整数n和m,0<n<21,0<m<1000000001。
    第二行n个整数表示居民们的重要度。
    重要度在[1,1000000000]之间。

    输出描述:

    一个整数表示最少需要多少把锁。
    示例1

    输入

    复制
    4 3
    1 1 1 1

    输出

    复制
    6

    说明

    106号房共有4名居民,只有3人在场时才能打开门。这时共需6把锁。


    解题思路:一开始没有想出来。。。我们可以这么想:当某个集合的重要度的总和没有到达m,但是再加上任意一个人,他们的重要度就能满足要求。我们假设这个集合缺少一把钥匙,我们求出所有的这样的集合,使得这些集合都缺少一把不同的钥匙,此时所有满足这样条件的集合数量即为所需要的锁的数量了。
    #include<bits/stdc++.h>
    using namespace std;
    long long a[25];
    long long dp[1<<21];
    int main(){
        long long n,m;
        scanf("%lld%lld",&n,&m);
        for(int i=0;i<n;i++){
            scanf("%lld",&a[i]);
           // dp[1<<i]=a[i];
        }
        long long ans=0;
        for(int i=0;i<(1<<n);i++){
            int flag=1;
            for(int j=0;j<n;j++){
                if((i&(1<<j))==0){
                    dp[i|(1<<j)]=dp[i]+a[j];
                    if(dp[i|(1<<j)]<m)flag=0;
                }
            }
            if(dp[i]<m&&flag)ans++;
        }
        printf("%lld
    ",ans);
       // for(int i=1;i<1<<n;i++)cout<<dp[i]<<" ";
        return 0;
    }
  • 相关阅读:
    Pandas包对多个数据表(DataFrame)的常用整合功能。
    pandas numpy 简单应用 loandata
    榛果 美团 登录 爬虫 requests session
    python 日期循环
    opencv 验证码 识别
    运行MapReduce任务
    CenOS安装MySQL服务
    leetcode 67. 二进制求和
    最近对一些领域比较感兴趣,这里列举出来供以后查阅
    leet code 1014. 最佳观光组合
  • 原文地址:https://www.cnblogs.com/Zhi-71/p/11503934.html
Copyright © 2011-2022 走看看