利用位运算来求组合问题:

题目如下:

链接:https://ac.nowcoder.com/acm/contest/303/D
来源:牛客网
 

星际争霸(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可以把所有情况都表示出来,然后找到其中的最优解,也可以使用dfs来做对于每一个位置的数加或者不加,最后输出最优解;

位运算代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define pi acos(-1)
//#define e exp(1)
#define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++)
#define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --)
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define eps 1e-7
#define INF 0x3f3f3f3f
#define inf -2100000000
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxn = 100 + 10;
const double EPS = 1e-10;
const ll p = 1e7+9;
const ll mod = 1e9+7;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
inline int read(){
    int ret=0,f=0;char ch=getchar();
    while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar();
    while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
    return f?-ret:ret;
}
int t;
struct node{
	int x,y;
}a[10];

int main(){
	ios::sync_with_stdio(false);
	cin >> t;
	
	int n;
	while(t--){
		cin >> n;
		int q = (1 << 7);
		for(int i = 0; i < 7; i++){
			cin >> a[i].x >> a[i].y;
		}
		int minn = 0;
		int maxnn = 0;
		int ans = 0;
		int sum = 0;
		for(int i = 0; i < q; i++){
			minn = 0;
			maxnn = 0;
			ans = 0;
			for(int j = 0; j < 7; j++){
				if(i&(1<<j)){
					minn += a[j].x;
					maxnn += a[j].y;
					ans ++;	
				}
				if(minn <= n && maxnn >= n){
					sum = max(ans,sum);
				}
			}
		}
		cout << sum << endl;
	}
	return 0;
}

dfs代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define pi acos(-1)
#define e exp(1)
#define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++)
#define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --)
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define eps 1e-7
#define INF 0x3f3f3f3f
#define inf -2100000000
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxn = 100 + 10;
const double EPS = 1e-10;
const ll p = 1e7+9;
const ll mod = 1e9+7;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
inline int read(){
    int ret=0,f=0;char ch=getchar();
    while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar();
    while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
    return f?-ret:ret;
}
int t;
struct node{
	int x, y;
}a[10];
int sum = 0;
int n;
void dfs(int l, int r, int ans, int m){
	if(ans == 7){
		if(l <= n && r >= n){
			sum = max(sum, m);
		}
		return ;
	}else{
		dfs(l+a[ans].x, r + a[ans].y, ans+1, m+1);
		dfs(l,r,ans+1, m);
	}
	return ;
}
int main(){
	ios::sync_with_stdio(false);
	cin >> t;
	while(t --){
		cin >> n;
		for(int i = 0; i < 7; i++){
			cin >> a[i].x >> a[i].y;
		}
		sum = 0;
		dfs(0,0,0,0);
		cout << sum << endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/ab1605014317/article/details/84897924