題意:
在一家超市裡,每個時刻都需要有營業員看管,r(i) (0 <= i < 24)表示從i時刻開始到i+1時刻需要的營業員的數目,現在有n(n <= 1000)個申請人申請這項工作,並且每個申請者都有乙個起始工作時間 ti,如果第i個申請者被錄用,那麼他會從ti時刻開始連續工作8小時。現在要求選擇一些申請者進行錄用,使得任何乙個時刻i,營業員數目都能大於等於r(i)。求出至少需要錄用多少營業員。
分析:
每天的工作情況都是一樣的,我們只需要求出一天的即可。根據題意,令s[i]為一天內前i+1個小時錄用的人數,如果i>=7,則s[i] - s[i-8] >= r[i],如果0 <= i < 7,則可以推出s[23] - s[i+16] + s[i] >= r[i],同時每個時刻錄用的人數有個上限,假設第i時刻最多可以錄用的人數為b[i],則對於每乙個i有0 <=s[i] - s[i-1] <= b[i]。
現在需要解決的乙個問題是,第二個不等式中包含3個s組的變數,這該怎麼建圖呢?可以知道我們只需要列舉s[23],那麼這個量就是已知的了,因此不等式可以變為s[i] - s[i+16] >= r[i] - s[23],但是必須明白的一點是,既然s[23]是列舉的一天的錄用人數的最小數目,我們建圖之後求出的s[23]也應該為列舉的那個值,可以從0到n列舉s[23],第乙個值便是答案,但是可以更高效地求解,因為問題具有單調性,直接二分.
因為s[-1] = 0,-1無法表示,只需要向右移動乙個單位即可,那麼令s[0] = 0,思路很清晰了,二分s[24]搜尋最小值。
**:
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
const
int inf =0x3f3f3f3f;
int r[30],time[30],cnt,head[30],d[30],vis[30];
queue
q;void init()
struct edge
; edge(int _v,int _w,int _next)
} edge[100000];
void add_edge(int u,int v,int w)
int spfa(int s)}}
return d[24]==s? 1: 0;
}int main()
int l =-1,r =n+1,m;
while(r-l>1)//都往右移乙個單位
add_edge(0,24,m);
add_edge(24,0,-m);
spfa(m)? r=m:l=m;
}l >= n ? puts("no solution") : printf("%d\n", r);
}return
0;}
POJ 1275 二分 差分約束系統
題意 傳送門 poj 1275 cashier employment 題解不等式問題,考慮轉化為差分約束系統。某個時刻 i ii 的工作人數為前 8 88 個小時內開始工作的人數和,將其轉化為字首和 s ss 的差分。設 num i num i num i 為工作開始時間為時刻 i ii 的人數。s...
poj1275 差分約束系統
1.思路 沒什麼好講的,劉汝佳的書 演算法藝術與資訊學競賽 講得很好,不過對於初次接觸差分約束系統的人來講還是很費解,可以去參考 演算法導論 裡面有很詳細的約束圖的構建過程。這裡講一下我的個人理解。s i 為從0至i時刻僱傭的人數,t i 為i時刻應聘的人數,r i 為i至 i 1 24時間段需要的...
POJ3169差分約束 SPFA 差分約束
思路 假設i j 兩隻奶牛可以站在同乙個位置,但是必須公升序排列,所以有差分約束方程d i d i 1 0 對於兩隻有好感的奶牛有差分約束方程d j d i k 對於兩隻反感的奶牛有差分約束方程d i d j k 有了約束方程就可以spfa include include include inclu...