題意:
在乙個國家當中,給你乙個詞彙書,你可以用裡面所有的字母拼湊出乙個單詞來,但是在這個國家當中存在一些禁用的單詞,那麼現在問你在不違反規則的情況下,你能盡可能的多拼湊出相應的單詞來。
那麼也就是說拼湊的單詞當中不能夠出現禁用的單詞的字段。
後面看到網上教程當中的dp狀態轉移,傻眼了。。這都可以。
dp[i+1][cnt]=dp[i+1][cnt]+dp[i][j],我所理解的就是在i+1這個位置上面我放上cnt這個字元,將之前可行的數目累加到長度為i+1的基礎上,其實我認為這個與其說是dp,倒不如說是一種遞推。
而其中的ac自動機就是用來判斷其中新拼湊的單詞當中是否出現過類似的字串,出現了就不能夠累加到相應的dp值上。
大數當然是因為方案的種類數多了之後難以用int整形存下。
**:view code
1//大數+dp+ac自動機
2 #include3 #include4 #include5 #include6 #include7
8const
int type=55;9
const
int max=800;10
const
intbase=100000000;11
const
int bit=30;12
13using
namespace
std;
1415
struct
node
16tree[max];
2122
struct
bignum
2331
}dp[type][max];
3233
int mm(int a,int
b)34
3738 bignum operator+(bignum a,bignum b)
3949
while
(k)50
54return
c;55}56
57int
n,m,p,tot;
58char
s[type],str[type];
59int dx[5*type];
6061 node *getroot()
6271 node *root;
7273 node *getnode()
7482
83void
insert()
8494 tmp->sum++;95}
9697
void
build_ac()
98119
}120
}121
}122
}123
124void
solution()
125139
else
140149
}150
if(now==null)now=root;
151int index=now->id;
152if(now->sum==0)dp[i+1][index]=dp[i+1][index]+dp[i][j];
153}
154}
155}
156}
157}
158void
init()
159168 root=getroot();
169while(p--)
170174
}175
void
print()
176193 printf("\n"
);194
}195
intmain()
196
POJ1625 AC自動機 DP 大數
題解 跑一遍ac自動機,後直接在上面dp一維表示字元長度二維表示處於那個結點最後標記一下那些位置是危險結點不要轉移過去即可,由於這題資料很大又沒有取膜所以要用大數相加 include include include include includeusing namespace std const i...
poj 1625 AC自動機 動歸 大數加法
題意 給出乙個字符集v和p個模式串 長度小於10 問由這個字符集中字元組成的長度為n的且不包含任意乙個模式串的字串有多少個?字符集大小,n 50,p 10 思路 先將p個模式串建立ac自動機,標記好危險節點 flag陣列 然後動歸來求 dp i j 表示長度為i且最後在節點j的字串個數 節點j必為安...
poj 1625 (AC自動機好模版,大數好模版)
題目 給n個字母,構成長度為m的串,總共有n m種。給p個字串,問n m種字串中不包含 不是子串 這p個字串的個數。將p個不能包含的字串建立ac自動機,每個結點用val值來標記以當前節點為字尾的字串是否包含非法字串 p個字串中的任何乙個 狀態轉移方程 f i,j f i 1,k f i,j 表示長度...