描述有n位工作人員,同時有n項任務, 每人必須承擔一項任務,若給出某人不能從事的某些任務, 問要安排好工作,共有多少種方案?
分析容斥原理的應用.
先看看樣例:
四個人: a, b, c, d
a 不能選擇: 2
b 不能選擇: 2 3
c 不能選擇: 3 4
d 不能選擇: 4
總數是1~4全排列的個數 => 4! = 24
再考慮不能選的情況
那麼 =>
採用 總數-非法個數 的方法計算, 而後者需用容斥原理計算.
answer :
= 4! - (|非法a + 非法b + 非法c + 非法d|)
= 4! -
= 4! - 3! - 2 * 3! - 2 * 3! - 3! + 2! + 2 * 2! + 2! + 3 * 2! + 2 * 2! + 2! - 1 - 1 - 1 - 1 + 0
= 4容斥的實現
據說有三種實現容斥原理的方法 :
1. dfs
2. 佇列陣列
3. 二進位制
只學了dfs法.
核心是統計各個階乘的係數(coe), 記錄在陣列裡, 最後高精統計.
根據 answer 的計算式子, 可以發現 : |p1 並 … pm| m為奇數時, (n-m)! 的係數是負的. 容斥原理裡這裡是正的, 但別忘這裡前頭還有負號.
感覺這個dfs怪怪的… 先遞迴到底層, 又邊回溯邊更改.
變數表.
main() :
fac: 階乘
cnt: 限制關係的個數
x: 人物
y: 任務
x <==> y // 一一對應
dfs() :
// 時間複雜度: o(2^15 = 32768)
coe 統計各個階乘被計算了多少次
cur: 當前不匹配關係的編號
visx: 此人以考慮過
visy: 此任務已有人做
num: 當前正在統計 n-num 的階乘的出現次數
|a1並a2並…並anum|
num 為偶數 => coe[n-num]++
num 為奇數 => coe[n-num]–
**19ms 4mb
#include
#include
#include
#include
#include
using
namespace
std;
const
int maxn = 100 + 10;
struct bigint
while(n > 0 && a[n - 1] == 0) n--;
return *this;
}bigint operator -= (const bigint& x)
a[i] -= x.a[i];
}while(n > 0 && a[n - 1] == 0) n--;
return *this;
}bigint operator * (const
int& x)
while(ans.n > 0 && ans.a[ans.n - 1] == 0) ans.n--;
return ans;
}void print()
};int n, cnt, x[maxn], y[maxn], coe[maxn];
bool visx[maxn], visy[maxn];
bigint ans, fac[maxn];
// 當前正在考慮第 cur 對不匹配關係
// 正在計算 |a1 並 a2 並 ... 並 anum|
void dfs(int cur, int num)
}}int main() };
for(int i = 1; i <= n; i++)
fac[i] = fac[i - 1] * i;
string tmp;
getline(cin, tmp);
for(int i = 0, j; i < n; i++)
}dfs(1, 0);
// 統計
for(int i = 0; i <= n; i++)
if(coe[i] > 0) ans += fac[i] * coe[i];
for(int i = 0; i <= n; i++)
if(coe[i] < 0) ans -= fac[i] * (-coe[i]);
ans.print();
return
0;}
主頁
1301 任務分配
2003年浙江省隊選拔賽 時間限制 1 s 空間限制 128000 kb 題目等級 大師 master 題解檢視執行結果 有n位工作人員,同時有n項任務,每人必須承擔一項任務,若給出某人不能從事的某些任務,問要安排好工作,共有多少種方案?輸入描述 input description 輸入檔案第1行為...
t057 任務分配
time limit 1 second memory limit 128 mb 問題描述 現有n個任務,要交給a和b完成。每個任務給a或給b完成,所需的時間分別為ai和bi。問他們完成所有的任務至少要多少時間。輸入格式 第一行乙個正整數n,表示有n個任務。接下來有n行,每行兩個正整數ai,bi。輸出...
hdu 4864 任務分配貪心
有n臺機器,m個任務,每台機器有xi時間,yi等級,每個任務也有xj,yj,當乙個任務可以被處理的條件是,xj xi 且 yj 對於每個任務,時間大的優先去匹配,時間相同的,等級大的優先去匹配,因為時間佔得多,時間多1就多500,而等級最多才差200。然後匹配的時候,盡量使用等級小的去匹配,而時間只...