zoukankan      html  css  js  c++  java
  • POJ1275 Cashier Employment 【二分 + 差分约束】

    题目链接

    POJ1275

    题解

    显然可以差分约束
    我们记(W[i])(i)时刻可以开始工作的人数
    (s[i])为前(i)个时刻开始工作的人数的前缀和

    每个时刻的要求(r[i]),可以通过如下限制满足:

    [s[i] - s[i - 8] ge r[i] ]

    [0 le s[i] - s[i - 1] le W[i] ]

    但是(i - 8)可能为负,回到上一天的时刻,导致区间不连续,不好处理
    我们可以二分答案(sum)
    (i < 8)的部分改为:

    [s[i + 16] - s[i] le sum - R[i] ]

    再加一个

    [s[24] - s[0] ge sum ]

    这样就可以了

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<map>
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define mp(a,b) make_pair<int,int>(a,b)
    #define cls(s) memset(s,0,sizeof(s))
    #define cp pair<int,int>
    #define LL long long int
    using namespace std;
    const int maxn = 105,maxm = 1000005,INF = 1000000000;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
    	while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
    	return out * flag;
    }
    int h[maxn],ne;
    struct EDGE{int to,nxt,w;}ed[maxm];
    inline void build(int u,int v,int w){
    	ed[++ne] = (EDGE){v,h[u],w}; h[u] = ne;
    }
    int n,R[50],W[50];
    int d[maxn],vis[maxn],cnt[maxn];
    int q[maxm],head,tail;
    bool spfa(){
    	for (int i = 0; i <= 24; i++) d[i] = -INF,vis[i] = false,cnt[i] = 0;
    	d[0] = 0; q[head = tail = 0] = 0;
    	int u;
    	while (head <= tail){
    		u = q[head++];
    		vis[u] = false; cnt[u]++;
    		if (cnt[u] >= 25) return false;
    		Redge(u) if (d[to = ed[k].to] < d[u] + ed[k].w){
    			d[to] = d[u] + ed[k].w;
    			if (!vis[to]) vis[to] = true,q[++tail] = to;
    		}
    	}
    	return true;
    }
    bool check(int sum){
    	for (int i = 1; i <= 24; i++) if (R[i] > sum) return false;
    	cls(h); ne = 0;
    	for (int i = 1; i < 8; i++) build(i + 16,i,R[i] - sum);
    	for (int i = 8; i <= 24; i++) build(i - 8,i,R[i]);
    	for (int i = 1; i <= 24; i++){
    		build(i - 1,i,0);
    		build(i,i - 1,-W[i]);
    	}
    	build(0,24,sum);
    	return spfa();
    }
    int main(){
    	int T = read();
    	while (T--){
    		for (int i = 1; i <= 24; i++)
    			R[i] = read(),W[i] = 0;
    		n = read(); int x;
    		REP(i,n){
    			x = read() + 1;
    			W[x]++;
    		}
    		int l = 0,r = n,mid,flag = false;
    		while (l < r){
    			mid = l + r >> 1;
    			if (check(mid)) r = mid,flag = true;
    			else l = mid + 1;
    		}
    		if (!flag) puts("No Solution");
    		else printf("%d
    ",l);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    .Net Core 自动化部署:使用jenkins部署到linux docker容器运行
    .Net Core 自动化部署:使用docker版jenkins部署dotnetcore应用
    React 使用browserHistory项目访问404问题
    使用Visual Studio Code和typescript 开发调试React Native项目
    java 基础
    javascript设计模式(1)——面向对象基础
    如何形成高度自律
    数据可视化-gojs插件使用技巧总结
    Git命令总结
    开源Git代码托管平台
  • 原文地址:https://www.cnblogs.com/Mychael/p/9160641.html
Copyright © 2011-2022 走看看