牛客 膜法記錄 狀壓dp預處理

2021-10-04 09:14:01 字數 1044 閱讀 4756

題目大意:給出乙個 n * m 的矩陣,其中存在著些許敵人,現在可以進行 a 次行攻擊,以及 b 次列攻擊,顧名思義,每次行攻擊可以消滅一整行的敵人,每次列攻擊可以消滅一整列的敵人,現在問能否通過合適的搭配,使得敵人全部消滅

題目分析:因為 n 最大只有20,所以考慮狀態壓縮預處理,對於每一列來說,所有敵人的位置肯定都有乙個狀態 state ,維護一下 dp[ i ] 表示二進位制下的字首和,維護方程為 if( ( i | j ) == i ) dp[ i ] += dp[ j ] ,預處理好後就可以列舉二進位制判斷了,對於每個狀態:

需要將每個狀態中的 1 進行 行攻擊,所以該狀態中 1 的個數需要小於等於 a

剩餘需要列攻擊的列共有 m - dp[ i ] 個,滿足該數字小於等於 b 即可

通過這個題學到了乙個偷懶的函式:__builtin_popcount( i ) 以讀表的形式返回32位整數 i 中有多少個 1 ,效率極高

**:

#include#include#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;

typedef long long ll;

typedef unsigned long long ull;

const int inf=0x3f3f3f3f;

const int n=1e5+100;

char maze[25][n];

int num[(1<<20)+100];

int main()

for(int i=0;ifor(int j=0;j<1

for(int i=0;i<1

if(flag)

puts("yes");

else

puts("no"); }

return 0;

}

牛客小白月賽23 A 膜法記錄(貪心 列舉)

題目傳送 用貪心的思想,先將行全部消滅,在判斷列有多少,和b比較一下。每一行可以消或不消,列舉2 n。include include include using namespace std const int maxm 1e5 5 int n,m,a,b,flag char map 30 maxm ...

狀壓DP 牛客練習賽57C 裝貨物

開二維肯定會爆記憶體了,箱子只有21個,我們考慮用狀壓dp來做。並且開兩個一維的。乙個代表為i狀態至少需要用多少個箱子,乙個表示用到第m個箱子的時候我們當前箱子剩餘的最大容量。分兩種情況轉移 1,我們當前的這個箱子剩餘容量夠裝,並且我們上一次裝了這個物品所用的箱子的狀態大於目前能裝且不用多餘箱子的狀...

膜法記錄(牛客小白月賽23 A,子集字首和)

中文題 由於 n 只有 20,考慮二進位制列舉操作的行 因此我們只需預處理出對行進行 i 操作後,零列的個數,記為 cnt i 先求出列狀態為 i 的列的個數,記為 cnt2 i 中.那麼 cnt i sum cnt2 i 的子集 例如求出列狀態數 cnt2 00 cnt2 01 cnt2 10 c...