i]表示
i 這個狀態最少能分多少組,列舉狀態,用它的子集更新狀態就可以了。
子集列舉。顯然可以列舉所有小於等於該狀態的數,但還有更快的方法:比如列舉狀態x的所有子集,可以這樣寫:for(int i=x;i;i=(i-1)&x)。i就為x的所有子集。感性的理解:x中某位為1,子集中該位為0或1;x中某位為0,子集中該位只能是0。&x就保證了第二點。
#include
#include
#include
#include
using
namespace
std;
const
int maxn=(1
<<17);
int n,m,k,f[maxn];
bool
map[18][18];
int main()
memset(f,63,sizeof(f));
for(int i=0;i
for(int j=0;jfor(int k=0;kif(map[j][k]&&(1
<1
<=k)f[i]=1;
for(int j=i;j;j=(j-1)&i)f[i]=min(f[i],f[j]+f[i^j]);
}printf("%d",f[(1
<1]);
}
tyvj P1403 關押罪犯 題解
p1403 noip2010 關押罪犯 s 城現有兩座監獄,一共關押著n 名罪犯,編號分別為1 n。他們之間的關係自然也極不和諧。很多罪犯之間甚至積怨已久,如果客觀條件具備則隨時 可能爆發衝突。我們用 怨氣值 乙個正整數值 來表示某兩名罪犯之間的仇恨程度,怨氣值越大,則這兩名罪犯之間的積怨越多。如果...
tyvj 4869 罪犯分組 狀壓DP
炸一看題目,無向圖?矛盾關係?難道是個圖論?顯然,資料範圍打消了我的顧慮。16?顯然是狀態亞索。不過之後就卡這了,但經過oblack的一番指導 ob真是太棒了 終於凌晨在寢室裡用手機a了這道。f s 記錄當前已處理的罪犯集合的最小小組數量。對於狀態s,列舉記錄集合中罪犯的矛盾數,若滿足條件,則就可以...
TYVJ4869 罪犯分組 狀壓DP列舉子集
資料範圍這麼小,很容易考慮到狀壓dp。預處理出所有情況的罪犯矛盾數並判斷哪些狀態是不合法的。之後就轉換為了乙個比較簡單的揹包dp問題。狀態轉移方程 f s m in f i 1 i 為s的子 集,且i xors 表示的集 合中矛盾 數不超過 k 問題似乎解決了,但是有乙個問題 如何高效列舉s的子集?...