題目描述
一組單詞是安全的,當且僅當不存在乙個單詞是另乙個單詞的字首,這樣才能保證資料不容易被誤解。現在你手上有乙個單詞集合,你需要計算有多少個子集是安全的。
注意空集永遠是安全的。
輸入格式
第一行乙個數
表示集合的大小,以下n行。每行乙個由
構成的字串。
輸出格式
安全子集的個數。
樣例輸入 #1
3hello
hell
hi輸出 #1
首先:設dp[i]表示前i個集合以i結尾的集合數
核心**:dp[i] = dp[j](1<=j但是問題在於與j不互為字首的單詞不一定與i不互為字首,這裡直接從小到大排序就可以解決
引理:把這些字串排序後,對於任意一組j這裡排序後的n個數沒有變,求解空間是一樣的。若不排序,則答案一定會偏大(有些決策會被計算,實際並不符合),而不會偏小。其實排序只是利用引理讓決策集合有序。
亮**:
#include
#include
#include
using namespace std;
string s[55]
;int n,a[55]
[55];
long
long dp[55]
;int
check
(int x,
int y)
return0;
}int
main()
sort
(s+1
,s+n+1)
;long
long ans=1;
for(
int i=
2;i<=n;i++
)for
(int j=i-
1;j>=
0;j--)if
(check
(i,j)
) dp[i]
+=dp[j]
;for
(int i=
1;i<=n;i++
) ans+=dp[i]
;printf
("%lld"
,ans)
;return0;
}
D Cleaning 思維好題 字首)
題意 n個數,現在你可以取出相鄰的都不為0的數,使得他們同時減1,如果乙個堆為0了,它並不會消失掉,此時我們有至多一次機會操作,交換相鄰兩個數的位置,問能不能使得全部的數都變為0.思路 首先發現,端點一定要 後面的值,不然肯定不成立。於是a2 a1,減了之後a2 a2 a1 此時a2變成端點,同理可...
題解 字首單詞
一組單詞是安全的,當且僅當不存在乙個單詞是另乙個單詞的字首,這樣才能保證資料不容易被誤解。現在你手上有乙個單詞集合,你需要計算有多少個子集是安全的。注意空集永遠是安全的。首先 設dp i 表示前i個集合以i結尾的集合數 核心 dp i dp j 1 j但是問題在於與j不互為字首的單詞不一定與i不互為...
trie樹 dp 字首單詞
讓我們一起來 forever shi神犇 題意 給你n個字串,每次選出若干個字串形成乙個集合,問有多少個集合滿足集合中的任何乙個字串都不是另外乙個字串的字首。空集也一定是滿足條件的。保證不會出現兩個相同的字串。首先對所有字串建出一棵tri etrie trie 樹,然後我們可以發現其實tri etr...