【牛客 - 303D第十五届浙江大学宁波理工学院程序设计大赛(同步赛)】Campaign(二进制枚举,位运算,暴力,思维)

版权声明:欢迎学习我的博客,希望ACM的发展越来越好~ https://blog.csdn.net/qq_41289920/article/details/84899938

题干:

星际争霸(StarCraft)单人战役模式中有很多供人游玩的任务关卡。

tokitsukaze新开始了一关单人战役模式下的任务。在这场战役中,你要作为指挥官指挥克鲁普星区的艾伦人类(Terran)来防御人类的敌人——邪恶异虫(Zerg)的袭击。

这一次,作为指挥官,你的任务目标是尽可能多的保全人类方所拥有的7个基地。你在这次任务中拥有n个人口单位的兵力。为了防御异虫的攻击,每个基地都有一个能够抵挡异虫攻击的最小兵力需求L[i],同时每个基地因为有固定的人口上限,分配给该基地的兵力也不得大于上限R[i]。

你需要在任务一开始就为这7个基地做好兵力分配,每个兵都应该分配给一个基地,即不应该有空闲兵力。如果任何一个基地被异虫攻破(分配的兵力大于0,且小于最小兵力需求,导致兵力白白葬送牺牲),或者某个基地的人口超过了人口上限,兵力大于R[i],任务都会直接失败。

为了避免任务失败,tokitsukaze决定从一开始就放弃一些基地(即不对这些基地派出兵力)。

请问保证任务成功的条件下,tokitsukaze最多留下多少个基地?特别的,如果任务失败这种情况下请输出"0",不含引号。

由于tokitsukaze的星际操作十分流弊,你可以认为如果能够至少能够保留一个基地,任务就一定能够成功。

输入描述:

第一行输入一个T(T≤50000),表示T组数据。

对于每组数据:
输入一个正整数n(1≤n≤10^9)表示需要分配的兵力总人口。
接下来7行,每行两个正整数L,R(1≤L≤R≤10^9),分别表示该基地够抵挡异虫攻击的最小兵力需求与该基地的人口上限。

输出描述:

对于每组数据,输出tokitsukaze最多能够留下几个基地,每组数据占一行。

示例1

输入

复制

4
50
1 1
1 1
1 1
1 1
1 1
1 1
1 1
50
1 1
20 30
20 30
20 30
1 1
20 30
20 30
70
19 19
10 10
10 10
10 10
10 10
10 10
1 1
2
1 1
3 3
3 3
3 3
3 3
3 3
3 3

输出

复制

0
4
7
0

说明

第一个样例,无论tokitsukaze怎么取舍,都不能满足条件。在这种特殊情况下你应该输出0。

第二个样例,tokitsukaze选择第一个第二个第三个和第五个基地,分别分配1,20,28,1的兵力即可满足既能完全分配兵力,同时这4个基地既能防御异虫的攻击,也不超过每个基地的人口上限。

第三个样例,tokitsukaze分别分配19,10,10,10,10,10,1给7个基地就能保证既能完全分配兵力,同时这7个基地既能防御异虫的攻击,也不超过每个基地的人口上限。

第四个样例,tokitsukaze如果只选择1号基地,那么要么无法将所有的兵力完全分配,要么该基地的人口总数将会大于上限,所以任务会直接失败,而如果选择其他基地,那么由于不能达到防御的最小下界。所以也会导致任务失败。不论怎么取舍任务都会失败,所以这种情况下应该输出0。

解题报告:

   就是个枚举答案,,实在不行就7层循环、、然后维护一个可行的l,r,当可行的l,r包含了输入的数的时候,就是满足条件的,然后从所有答案中选出最大的就行。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
ll n;
ll low[15],up[15];
bool fit(ll i,int j) {
	if((i>>j)&1) return 1;
	else return 0 ;
}
int get(ll i) {
	int cnt = 0;
	while(i) {
		if(i&1) cnt++;
		i>>=1; 
	}
	return cnt;
}
int main()
{
	int t;
	cin>>t;
	while(t--) {
		scanf("%lld",&n);
		int ans = 0;
		for(int i = 1; i<=7; i++) {
			scanf("%lld%lld",low+i,up+i);
		}
		ll minn = 0,maxx = 0;
		for(ll i = 0; i<(1<<7); i++) {
			minn=maxx=0;
			for(int j = 1; j<=7; j++) {
				if(fit(i,j-1)) minn+=low[j],maxx+=up[j];
			}
			if(minn<=n && maxx>=n) ans = max(ans,get(i));
		}
		printf("%d\n",ans);
	}
	return 0 ;
 }

%%%Qls:

#include<bits/stdc++.h>
using namespace std;
 
typedef long long ll;
 
ll l[15],r[15];
 
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<7;i++)
            scanf("%lld%lld",&l[i],&r[i]);
        int res=0;
        for(int i=0;i<(1<<7);i++)
        {
            ll mi=0,mx=0;
            for(int j=0;j<7;j++)
                if(i>>j&1)mi+=l[j],mx+=r[j];
            if(mi<=n && n<=mx)
                res=max(res,__builtin_popcount(i));
        }
        printf("%d\n",res);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41289920/article/details/84899938