可以用二進位制表示子集,這種表示方法真的非常省時間空間,其中從右往左第i位(從0開始編號)表示元素i是否在集合中(1表示「在」,0表示「不在」)
e.g.
二進位制的1111換算成十進位制就是15,如果用15代表全集a的話,那麼1101b(b是二進位制)即13d(十進位制)就代表了a的乙個具有第1、第3、第5個元素的子集b。
本題的做法有很多。一種相對容易實現的方法是:用兩個集合s1表示恰好有乙個人教的科目集合,s2表示至少有兩個人教的科目集合,而d(i,s1,s2)表示已經考慮了前i個人時的最小花費。注意,把所有人一起從0編號,則編號0~m-1是在職教師,m~n+m-1是應聘者。狀態轉移方程為d(i,s1,s2) = min,其中第一項表示「聘用」,第二項表示「不聘用」。當i≥m時狀態轉移方程才出現第二項。這裡s1』和s2』分別表示「招聘第i個人之後s1和s2的新值」,具體計算方法見**。
下面**中的st[i]表示第i個人能教的科目集合(注意輸入中科目從1開始編號,而**的其他部分中科目從0開始編號,因此輸入時要轉換一下)。下面的**用到了乙個技巧:記憶化搜尋中有乙個引數s0,表示沒有任何人能教的科目集合。這個引數並不需要記憶(因為有了s1和s2就能算出s0),僅是為了程式設計的方便(詳見s1』和s2』的計算方式)。
#include
#include
using
namespace
std;
#include
#define maxs 10
#define maxn 130+10
#define maxm 30
#define inf 1000000000
int s,m,n,c[maxn],st[maxn],d[maxn][1
<1
int main()
else}}
int ans = dp(1, (1
<< s) - 1, 0, 0);
printf("%d\n", ans);
}return
0;}
UVA 木塊問題 101
uva 木塊問題 101,好開森好開森。雖然花了很長時間,不過能一次就ac也是蠻開心的,用c 寫效率就是不錯 疊木塊其實是乙個二維空間,每個木塊都有縱橫座標 include include includeusing namespace std block用於記錄木塊所在位置,x是位於哪一疊木塊,y是...
UVA 非常可樂
include include include include include using namespace std struct node int vis 205 205 注意vis陣列用於 int s,n,m int cup left 3 記錄三個杯子中每個杯子的剩餘狀態 int bfs fo...
UVa百題總結
總算刷夠 演算法競賽入門經典 100題了,就像教主所說,有了練acm的誠意,受自身水平和眼界所限,這總結難免會有一些個人色彩和不正確的地方,大牛勿噴。另外我的文筆可能極其拙劣,將就著看吧。按照教主的進度安排,最理想的情況是寒假學完前八章,下學期開始學動態規劃 數學和圖論的基礎,為暑假集訓打下基礎。暑...