時間限制: 2 sec 記憶體限制: 128 mb
提交: 134 解決: 18
[提交] [狀態] [討論版] [命題人:admin]
題目描述
adrian 很喜歡詩歌中的韻。他認為,兩個單詞押韻當且僅當它們的最長公共 字尾的長度至少是其中較長單詞的長度減一。也就是說,單詞 a 與單詞 b 押韻 當且僅當 lcs(a, b) ≥ max(|a|, |b|) – 1。(其中 lcs 是最長公共字尾 longest common suffix 的縮寫)
現在,adrian 得到了 n 個單詞。他想從中選出盡可能多的單詞,要求它們能 組成乙個單詞序列,使得單詞序列中任何兩個相鄰單詞是押韻的。
輸入第一行是乙個整數n。
接下來n行,每行乙個由小寫英文本母組成的字串,表示每個單詞。所有單詞互不相同。
輸出輸出一行,為乙個整數,表示最長單詞序列的長度。
樣例輸入
5
askpsk
kkrafna
sk
樣例輸出
4
提示
一種最長單詞序列是 ask-psk-sk-k。
30%的測試資料:1 ≤ n ≤ 20,所有單詞長度之和不超過 3 000。
100%的測試資料:1 ≤ n ≤ 500 000,所有單詞長度之和不超過 3 000 000。
2018北京冬令營1
【分析】
將所有單詞逆序,並建立字典樹,單詞結尾結點加標記。
問題就轉化為:
在字典樹上找一條最長的路徑,滿足 ①只走標記結點 ②從結點u可以走向父結點、孩子結點、兄弟結點。
設陣列 fdp[i] 表示以 i 結點為根節點時,可以從任一子樹走上來,剛走到 i 時的最長路徑(這是一條起始於子樹,終結於點 i 的路徑)。如圖藍色結點的藍色路徑為fdp表示最長路徑:
設陣列 dp[i] 表示以i結點為根節點時,把兩個擁有最長fdp的子樹連線起來,順便把所有孩子結點連上的最長路徑(這是一條從子樹起始,終結於子樹的路徑)。如圖粉紅色結點,把兩個擁有最大fdp的孩子連線到自己。
在dfs回溯過程中更新這兩個陣列即可。最後取陣列中的最大值即為答案
【**】
#includeusing namespace std;
typedef long long ll;
const int mod=1e9+7;
const int max=1e6+5;
struct nodeedge[max];
int cnt,head[max],val[max]; //val[i]結點i結尾的單詞數
void init()
void addedge(int u,char ch)
; head[u]=cnt;
}int new_word(char *str)
else if(mxchild>mx[0])mx[0]=mxchild;
mark+=val[i];
}mark+=val[u];
if(mx[0]>0)dp[u]=mx[0]+mx[1]+mark; //連線兩孩子
if(val[u])fdp[u]=mark+mx[1]; //最長單鏈
}char str[max];
int main()
dfs(0);
int ans=0;
for(int i=0;i<=cnt;i++)ans=max(ans,max(dp[i],fdp[i]));
printf("%d\n",ans);
}
636 函式的獨佔時間
題目 給出乙個非搶占單執行緒cpu的 n 個函式執行日誌,找到函式的獨佔時間。每個函式都有乙個唯一的 id,從 0 到 n 1,函式可能會遞迴呼叫或者被其他函式呼叫。日誌是具有以下格式的字串 function id start or end timestamp。例如 0 start 0 表示函式 0...
LeetCode636 函式的獨佔時間
給出乙個非搶占單執行緒cpu的n個函式執行日誌,找到函式的獨佔時間。每個函式都有乙個唯一的 id,從0到n 1,函式可能會遞迴呼叫或者被其他函式呼叫。日誌是具有以下格式的字串 function id start or end timestamp。例如 0 start 0 表示函式 0 從 0 時刻開...
nyoj 636 世界末日
時間限制 1000 ms 記憶體限制 65535 kb 難度 1 描述 世界末日馬上就要來臨了,當然,每個人都想買到船票,但是由於船票有限,因此需要回答對乙個問題才能買票。問題是這樣的 給你乙個數n 1 n 10000 之後給n個正整數 10000 問在這n個數中是否存在一些數的和是n的倍數。輸入 ...