zoukankan      html  css  js  c++  java
  • hdu1529 Cashier Employment[差分约束+二分答案]

    这题是一个类似于区间选点,但是有一些不等式有三个未知量参与的情况。


    依题意,套路性的,将小时数向右平移1个单位后,设$f_i$为前$i$小时工作的人数最少是多少,$f_{24}$即为所求。设$c_i$为第$i$小时可选人数,$lim_i$为要求人数下限。

    • $0le f_i-f_{i-1}le c_i$,保证合法
    • $ige 8$时,$f_i-f_{i-8}ge lim_i$
    • $i<8$时,由于环形,$f_i+(f_{24}-f_{i+16})ge lim_i$,但这个不好处理,因为这不是一个二元关系,有第三个未知数参与。不过分析可知这些不等式中参与的第三个量是同一个,那么我们可以暴力枚举这个$f_{24}$,然后化为二元,再建图看合不合法。
    • 使用上一条的方法时,注意限制$f_{24}-f_0=枚举的数$

    事实上,答案满足可二分性,于是改为二分答案,跑正环检验即可。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #define dbg(x) cerr << #x << " = " << x <<endl
     8 #define dbg2(x,y) cerr<< #x <<" = "<< x <<"  "<< #y <<" = "<< y <<endl
     9 using namespace std;
    10 typedef long long ll;
    11 typedef double db;
    12 typedef pair<int,int> pii;
    13 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
    14 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
    15 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
    16 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
    17 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
    18 template<typename T>inline T read(T&x){
    19     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
    20     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
    21 }
    22 const int N=1000,INF=0x3f3f3f3f;
    23 struct thxorz{int to,nxt,w;}G[N];
    24 int Head[26],tot;
    25 int cnt[26],lim[26];
    26 int T,n,L,R;
    27 inline void Addedge(int x,int y,int z){G[++tot].to=y,G[tot].nxt=Head[x],Head[x]=tot,G[tot].w=z;}
    28 int dis[26],inq[26],rel[26];
    29 #define y G[j].to
    30 inline bool spfa(){
    31     queue<int> q;
    32     for(register int i=0;i<=24;++i)q.push(i),dis[i]=0,inq[i]=1,rel[i]=0;
    33     while(!q.empty()){
    34         int x=q.front();q.pop();
    35         inq[x]=0;//dbg(x);
    36         for(register int j=Head[x];j;j=G[j].nxt)if(MAX(dis[y],dis[x]+G[j].w)){
    37             rel[y]=rel[x]+1;if(rel[y]>=25)return 0;//dbg(y);
    38             if(!inq[y])inq[y]=1,q.push(y);
    39         }
    40     }
    41     return 1;
    42 }
    43 #undef y
    44 inline bool check(int mid){
    45     memset(Head,0,sizeof Head),tot=0;
    46     for(register int i=1;i<=24;++i)Addedge(i-1,i,0),Addedge(i,i-1,-cnt[i]);
    47     for(register int i=8;i<=24;++i)Addedge(i-8,i,lim[i]);
    48     for(register int i=1;i<8;++i)Addedge(i+16,i,lim[i]-mid);
    49     Addedge(0,24,mid),Addedge(24,0,-mid);
    50     return spfa(); 
    51 }
    52 
    53 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
    54     read(T);while(T--){
    55         for(register int i=1;i<=24;++i)read(lim[i]);
    56         memset(cnt,0,sizeof cnt);
    57         read(n);for(register int i=1,x;i<=n;++i)read(x),cnt[x+1]++;
    58         L=0,R=n+1;//dbg(check(1)),dbg(check(2)),dbg(check(3)),dbg(check(4)),dbg(check(5));
    59         while(L<R){
    60             int mid=L+R>>1;
    61             if(check(mid))R=mid;
    62             else L=mid+1;
    63         }
    64         if(L<=n)printf("%d
    ",L);
    65         else puts("No Solution");
    66     }
    67     return 0;
    68 }
    View Code

    一道弱智小题耗我半小时。。

    RE记录:差分约束题建边老是容易在Addedge处写倒掉。注意本题$n$的意味,不要混淆成点数。

    总结:第三元参入不等式,二分答案检验。

  • 相关阅读:
    培训课程大纲
    十个心理细节
    海马记忆训练
    手把手教你_怎么找android应用的包名和启动activity
    LoaderManager使用具体解释(四)---实例:AppListLoader
    strtok函数
    猫猫学iOS 之微博项目实战(2)微博主框架-自己定义导航控制器NavigationController
    OpenCV实践之路——Python的安装和使用
    状态模式
    一个有意思的Ruby Webdriver超时问题的解决过程
  • 原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/11646780.html
Copyright © 2011-2022 走看看