題目大意:給出 n 個模式串每個模式串都有乙個價值,要求構造出乙個長度為 m 的字串,每個模式串出現一次都會得到一次相應的價值,問如何構造可以使得最終的價值總和最大
題目分析:做過一道加強版的題目:
多餘的功能刪掉就好,有個不太一樣的細節就是,上面的那個題目的字串不允許共用,但這個題目的字串允許共用,所以需要在 getfail() 函式中稍作修改,也就是說需要累加一下共用的字串的貢獻,剩下的直接 dp 就好了,dp[ i ][ j ] 代表構造長度為 i 的字串,當前狀態為 j 時的最大貢獻,傳遞的話在ac自動機的trie樹上跑就好了
**:
#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=2e3+100;
int n,m;
char s[n];
int fail[n],trie[n][26],cnt,sum[n];
vectorvis[n];
int dp[1010][n];//dp[i][j]:長度為 i ,狀態為 j 時的最大值
void insert_word(int val)
} while(!q.empty())
else
trie[cur][i]=trie[fail[cur]][i];
} }}
int main()
getfail();
memset(dp,-inf,sizeof(dp));
dp[0][0]=0;
for(int i=0;ifor(int j=0;j<=cnt;j++)
for(int k=0;k<26;k++)
int ans=-inf;
for(int i=0;i<=cnt;i++)
ans=max(ans,dp[m][i]);
printf("%d\n",ans);
return 0;
}
牛數 ac自動機 數字dp
給你n個數字串,定義牛數x n個數字串都不是x的子串。然後給你乙個長度為2000的數字s,問你 1,s 之間牛數有多少個。多個模式串匹配主串,就自然而然地會想到ac自動機了,然後問你 1,s 之間滿足條件的數的個數,那麼就是數字dp了,不過這裡的數字dp要在trie樹上跑,還要注意判斷前導零。inc...
關於AC自動機與DP的總結
ac自動機實際上是將字串集合與狀態一一對應,也算是一種狀態壓縮的手段。對於狀態,一般考慮這麼幾個要素 1.考慮到了主串的第幾位,這個一般就是狀態的要素之一 其中一維 空間不夠時可以考慮滾動陣列 i 1 2.自動機上的狀態。這裡注意自動機上的某點可能對應多個字串的最後一位,因此在設定失敗指標時,如有需...
暖 墟 AC自動機 AC自動機的總結與運用
kmp 匹配單串,線性掃瞄,在失配時用next陣列引導j指標回溯,進行下一步匹配。trie樹 多模式的匹配,構造26叉樹,同時記錄多個串的情況,記錄結尾,進行匹配。kmp trie樹 ac自動機 ac自動機 給乙個字典,再給乙個文字,問這個文字裡出現了字典裡的哪些字。可以用n個單詞的n次kmp演算法...