题解 P1666 前缀单词
这道题我们考虑dp。
令 表示以 结尾的满足条件的子集个数。
例如在样例中, 就是 ,因为以 为结尾且满足条件的子集数只有它本身。
初始条件是 ,因为无论如何,自己本身永远都是安全的。
接下来转移就是显然的:
当且仅当 可以共存。
如何判断能否共存的?
用这个引理:
把这些字符串排序后,对于任意一组 且他们不互为前缀,则对于任意一组 且他们不互为前缀,则 与 不互为前缀。
注意,这里排序是必须的,否则他会把一些不符合条件的子集算进去。
答案显然就是所有 的和再加一。因为空集也算。
#include<bits/stdc++.h> using namespace std; #define int long long int n; const int N=2010; string s[N]; int dp[N]; int ans; bool check[N][N]; bool pd(int i,int j) { if(s[i].size() < s[j].size()) swap(i,j); return s[i].find(s[j])!=0; } signed main() { cin>>n; for(int i=1;i<=n;i++) cin>>s[i]; sort(s+1,s+1+n); for(int i=1;i<=n;i++) { dp[i]=1; for(int j=1;j<=n;j++) { check[i][j]=pd(i,j); } } for(int i=1;i<=n;i++) { for(int j=i;j<=n;j++) { if(check[i][j]==1)dp[j]+=dp[i]; } } for(int i=1;i<=n;i++) { ans+=dp[i]; //cout<<dp[i]<<endl; } cout<<ans+1<<endl; return 0; }
本文作者:zplqwq
本文链接:https://www.cnblogs.com/zplqwq/p/16397658.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步