BZOJ1879bill的挑戰 狀壓DP

2021-08-19 18:42:19 字數 1422 閱讀 2740

本題包含多組資料。

第一行:乙個整數t,表示資料的個數。

對於每組資料:

第一行:兩個整數,n和k(含義如題目表述)。

接下來n行:每行乙個字串。

t ≤ 5,m ≤ 15,字串長度≤ 50。

output

如題sample input

3 3???r???

3 4?????a?

3 3?a??j??

????aa?

3 2a??????

3 2???a???

????a??

sample output

這道題一看就是狀壓dp,然而我們很難直接推出。我們可以換乙個思路,先預處理出陣列g。

陣列g[i][j]表示字串到第i位,並且這位上選擇小寫字母j所符合的個數。(用二進位制表示)那麼我們可以推出g[i][j]的表示方式:

for(int i=0;i

i++)

for(int j=0;j

<26;j++)

for(int k=1;k<=n;k++) if(s[k]

[i]=='?'||s[k]

[i]==(j+'a')) g[i]

[j]|=1

<1;

我們預處理出g陣列之後就可以發現乙個dp了:
f[(1

<1]

[0]=1;

for(int i=0;i

i++)

for(int j=0;j

if(f[j]

[i]) for(int k=0;k<26;k++) f[j&g[i]

[k]][i+1]=(f[j&g[i]

[k]][i+1]+f[j]

[i])%md;

ans=0;

這個dp的f[i][j]表示二進位制狀態為i,dp到第j位時的方案數,最後輸出所有的f[i][len],其中i滿足二進位制下有k個1即可。
#include

#define md 1000003

using

namespace

std;

int read()

int t,n,m,len,ans,g[105][105],f[1

<<15][105];

string s[105];

int main()

if(sum==m) ans=(ans+f[i][len])%md;

}printf("%d\n",ans);

}return

0;}

狀壓DP之Bill的挑戰

p2167 sdoi2009 bill的挑戰 sheng bill不僅有驚人的心算能力,還可以輕鬆地完成各種統計。在昨天的比賽中,你憑藉優秀的程式與他打成了平局,這導致sheng bill極度的不滿。於是他再次挑戰你。這次你可不能輸!乙個不服輸讓我這個ruoji碼了倆小時 這次,比賽規則是這樣的 給...

題解 SDOI2009 Bill的挑戰 容斥

給n nn個字串,每個字串由a z或者?組成,其中?可以匹配任意字元。現在問有多少個串t tt,滿足能夠恰好與n nn個串中的k kk個匹配。n 20 n leq 20,n 20 字串長度 50 leq 50 50。這是一道容斥題,當然一看資料範圍也可以用狀壓dpdp dp寫。考慮我們能夠預處理出什...

BZOJ3029 守衛者的挑戰

第一行三個整數n,l,k。第二行n個實數,第i個實數pi表示第i項挑戰成功的百分比。第三行n個整數,第i個整數ai表示第i項挑戰的屬性值.乙個整數,表示所求概率,四捨五入保留6 位小數。樣例輸入1 3 1 0 10 20 30 1 1 2 樣例輸入2 5 1 2 36 44 13 83 63 1 2...