PTA------>摆放小球

描述了一个涉及空盘子、条件和学生选择的小球放置问题,通过二进制枚举策略寻找最多满足条件的方案,时间复杂度分析
摘要由CSDN通过智能技术生成

一,题目:

有n个空盘子摆放在桌子上,编号依次为1 - n,以及m个条件,编号依次为1 - m。
第i个条件满足时当且仅当第 ai​ 和第 bi ​个盘子中均存在小球。
有k名同学,编号依次为1 - k,第i名同学会选择在编号为 ci ​者 di​ 的盘子中放一个小球。
请你求出最多有多少个条件能得到满足?

输入格式

第一行两个正整数,分别代表n和m
后面m行,每行两个正整数代表ai​和bi​。
然后一行一个正整数,代表k.
后面k行,每行两个正整数,分别代表ci​和di​。
2≤n≤100
1≤m≤100
1≤ai​<bi​≤n
1≤k≤16
1≤ci​<di​≤n

输出格式

输出一个整数代表答案

测试样例一
4 4
1 2
1 3
2 4
3 4
3
1 2
1 3
2 3
2
测试样例二
4 4
1 2
1 3
2 4
3 4
4
3 4
1 2
2 4
2 4
4
测试样例三
6 12
2 3
4 6
1 2
4 5
2 6
1 5
4 5
1 3
1 2
2 6
2 3
2 5
5
3 5
1 4
2 6
4 6
5 6
9

 二,思路:

这题看时间范围我们就可以大概猜出考察的东西了,时间范围很小一般会用到 dfs,bfs,dp,或者暴力枚举答案等等。这里我们可以直接枚举所有选法方案,那怎么枚举呢?当我们观察到 k<=16,我们可以联想到 2e16(时间复杂度约为1e4级别),那么我们可以直接枚举二进制数。当二进制某位上是一代表我们要选第2个,反之为0,我们选第1个。然后我们根据枚举到的方案去判断,最多有多少条件满足(时间复杂度 100)。

时间复杂度:1e4*100。

三,代码:

#include <iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<set>
#include<stack>
#include<queue>
#include<map>
using namespace std;

#define  x first
#define y second

const int N=110,M=1e9+7;

typedef  long long ll;
typedef pair<int,int> pii;
pii arr[N],brr[N];

void Solved() {

    int n,m;
    cin>>n>>m;

    for(int i=1;i<=m;i++){
        int a,b;
        cin>>a>>b;

        arr[i]={a,b};
    }

    int k;
    cin>>k;

    for(int i=0;i<k;i++){
        int a,b;
        cin>>a>>b;

        brr[i]={a,b};
    }


    int res=0;
//枚举二进制数
    for(int i=0;i<1<<k;i++){

//用set来储存我们枚举到的方案,涵盖那些杯子
        set<int> s;
        for(int j=0;j<k;j++){
            if(i>>j&1) s.insert(brr[j].y);
            else s.insert(brr[j].x);
        }

//判断在该方案下最多有多少条件满足
        int cnt=0;
        for(int j=1;j<=m;j++){
            if(s.count(arr[j].x)!=0&&s.count(arr[j].y)!=0) cnt++;
        }

        res=max(res,cnt);
    }

    cout<<res<<endl;
}

int main()
{
    int t;
    t=1;

    while(t--) {
        Solved();
    }
    return 0;
}

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值