1301 任務分配

2022-05-03 10:39:19 字數 2880 閱讀 4257

2023年浙江省隊選拔賽

時間限制: 1 s

空間限制: 128000 kb

題目等級 : 大師 master

題解檢視執行結果

有n位工作人員,同時有n項任務, 每人必須承擔一項任務,若給出某人不能從事的某些任務, 問要安排好工作,共有多少種方案?

輸入描述 input description

輸入檔案第1行為n(1<=n<=100), 以下n行,其中第i+1行表示第i個人不能從事的任務編號, 任務之間用空隔分開, 若第i個人沒有限制條件,則第i+1行為空行, 所有人員不能從事的任務之和不大於25。

輸出描述 output description

輸出檔案只有1行,為所有滿足條件的分配方案數。

樣例輸入 sample input

2 33 4

樣例輸出 sample output

資料範圍及提示 data size & hint

如題分類標籤 tags 點此展開 

開放性試題

搜尋省隊選拔賽

2023年

分析

容斥原理的應用.

先看看樣例:

四個人: 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]–-

來自:ac**:

#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)

dfs(cur+1

,num);

if(!visx[x[cur]]&&!visy[y[cur]])

}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)

}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();

return0;

}

CODEVS 1301 任務分配

描述 有n位工作人員,同時有n項任務,每人必須承擔一項任務,若給出某人不能從事的某些任務,問要安排好工作,共有多少種方案?分析 容斥原理的應用.先看看樣例 四個人 a,b,c,d a 不能選擇 2 b 不能選擇 2 3 c 不能選擇 3 4 d 不能選擇 4 總數是1 4全排列的個數 4 24 再考...

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。然後匹配的時候,盡量使用等級小的去匹配,而時間只...