題目大意:
思路:
思路比較容易明白,就是**比較不容易寫,對位運算必須非常熟悉。
#include
using
namespace std;
int st[
150]
;int fy[
150]
;int s, n, m;
int dp[
150][(
1<<8)
+1][
(1<<8)
+1];
intdfs
(int i,
int s0,
int s1,
int s2)
else
}int
& ans=dp[i]
[s1]
[s2];if
(ans!=-1
) ans=
(10000000);
if(i>m)
//m+1-n+m才可以不選擇
int m0=s0&st[i]
;//之前沒有的&現在教的科目=新增加的科目
int m1=s1&st[i]
;//之前乙個人教&現在教的科目=新增加有兩個人教的科目
s0^=m0;
//現在沒有人教的科目=之前沒有人教的科目-新增加的科目
s1=(s1^m1)
|m0;
//現在乙個人教的科目=之前乙個教的科目-新增加有兩個人教的科目
s2=(s2)
|m1;
//現在有兩個人教的科目=之前有兩個人交的科目+新增加有兩個人教的科目
ans=
min(ans,
dfs(i+
1, s0, s1, s2)
+fy[i]);
//選擇這個老師
return ans;
}int
main()
}}cout<<
dfs(1,
(1<
,0,0
)<
}return0;
}
UVa 10817 狀壓 記憶化搜尋
描述 m個教師,n個求職者,s門課程.每門課程至少需要2個老師教,問符合要求的最小值 分析 首先定義狀態 對於每乙個老師只有教或者不叫兩種決策,而方程想要轉移,很容易看出需要知道此時老師教授的情況.故 定義 f i s1 s2 i表示依考慮到前i個老師 s1為乙個老師教的集合 s2為兩個老師教的集合...
UVA 10817 校長的煩惱
根據s的範圍我們可以考慮集合dp,一種相對容易的方法是用集合s1表示恰好有乙個人教授的科目集合,s2表示至少有兩個人教授的科目集合,f i,s1,s2 表示已經考慮了前i個人時的最小花費。狀態轉移方程為 f i,s1,s2 min其中第一種情況是聘用第i個人,第二種為不聘用。這裡要注意第二種情況當且...
基本的狀壓DP
給出乙個 times 要求棋子不相鄰,求方案數 n 100 m 8 f i s sum 為零表示不相鄰 s 表示當前行中棋子的情況 解析 我們會發現乙個問題,上述式子確實可以保證上下行不相鄰,但是左右呢,對於我這個剛認識狀壓的菜雞來說,很懵逼,答 狀態壓縮的本質 存在乙個維度是在進製級別表達多組狀態...