fjnu1197 蒟蒻的任务分配 bitset的使用

/*
    题目描述:给出n(n<= 1000)个任务,第i个任务需要耗费的时间为cost[i](cost[i]<=10),每个任务有一个兼容情况,0代表这个任
            务不能和其他任务同时进行,1代表这个任务可以和其他任务同时进行,每个时刻可以同时进行一个任务或两个任务,但进行两个任务的话要求
            这两个任务中至少有一个是1类型,现在问最少用多少时间可以进行完全部的任务。

    方法:注意到每项任务的耗时cost[i]小于等于10,所以任务的总时间小于10000,如果能处理出有这些任务能拼出的所有的时间长度,可以枚举
       第一条线上任务的总耗时t1,总时间减t1得到第二条线上的总耗时t2,那么这样的情况下的耗时t为max(t1 , t2),但要注意如果t小于
       所有0任务的总时长t0的话,那么答案应该是t0,因为短于这个时间不可能完成任务。

       那么,如何快速高效的处理出所有能拼出的长度呢?方法是使用bitset,可以O(n)处理出所有能拼出的长度。

    收获:1、bitset的有效使用能够处理复杂问题,其优势在于既能表示出很长的二进制串,还能O(1)的时间左移或右移某些位
        2、可以利用bitset求出一些整数能组成的所有整数
*/
#pragma warning(disable:4786)
#pragma comment(linker, "/STACK:102400000,102400000")
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
#define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define lson l,m,x<<1
#define rson m+1,r,x<<1|1
using namespace std;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double PI = acos(-1.0);
const double eps=1e-6;
const int maxn = 1e4 + 5;
int main()
{
    int T , n , x , f;
    scanf("%d", &T);
    while(T--){
        bitsetb;      //bitset声明,第i位是1表示可以拼出i
        b[0] = 1;
        scanf("%d", &n);
        int len0 = 0 , len1 = 0;
        for(int i = 1; i<= n;  i++){
            scanf("%d%d", &x , &f);
            if(!f)  len0 += x;
            else   len1 += x;
            b |= (b << x);
        }
        int ans = INF;
        for(int i = 1 ; i <= 10000 ; i++){
            if(b[i]){
                ans = min(ans , max(i , len0 + len1 -  i));
            }
        }
        ans = max(ans , len0);
        printf("%d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(基础数据结构)