博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P1666 前缀单词
阅读量:6188 次
发布时间:2019-06-21

本文共 1234 字,大约阅读时间需要 4 分钟。

P1666 前缀单词

题目描述

一组单词是安全的,当且仅当不存在一个单词是另一个单词的前缀,这样才能保证数据不容易被误解。现在你手上有一个单词集合S,你需要计算有多少个子集是安全的。

注意空集永远是安全的。

输入输出格式

输入格式:

 

第一行一个数n,表示集合的大小,以下n行。每行一个由’a’……’z’构成的字符串。

【数据规模】

对30%的数据,满足1≤n≤10;

对于100%的数据,满足1≤n≤50;字符串长度≤50,没有两个字符串是完全相同的。

 

输出格式:

 

安全子集的个数。

 

输入输出样例

输入样例#1: 
3hellohellhi
输出样例#1: 
6

 

枚举小状态来找状态转移方程

 

洛谷题解

我们预处理一个f[i][j]表示第i个单词与第j个单词是否能共存,

然后考虑一个dp[i]表示在前i个单词中,必须包含第i个单词的子集个数,首先dp[i]=1(只包含自己一个元素的一个子集方案数)

那么如果前面存在一个j<i,并且f[i][j]=1(即i与j可以共存),那么j所有的子集方案数加上一个i元素就形成了对应新的方案,那么状态就由j转移到i了,最后,直接累计dp[1....n]即可,当然最后还要算上空集哟。

参考代码:

1 #include
2 #include
3 #include
4 #define REP(i,a,b) for (register int i=(a);i<=(b);i++) 5 using namespace std; 6 const int N=61; 7 string a[N]; 8 long long f[N][N],dp[N]; 9 int n;10 inline bool calc(int i,int j){11 if (a[i].size()>a[j].size())swap(i,j);12 return a[j].find(a[i])!=0;13 }14 int main(){15 ios::sync_with_stdio(false);16 cin>>n;17 REP(i,1,n)cin>>a[i];18 sort(a+1,a+n+1);19 REP(i,1,n){20 dp[i]=1;21 REP(j,1,n)f[i][j]=calc(i,j);22 }23 REP(i,1,n)REP(j,i,n)dp[j]+=f[i][j]?dp[i]:0;24 long long ret=0;25 REP(i,1,n)ret+=dp[i];26 cout<

 

转载于:https://www.cnblogs.com/Renyi-Fan/p/7741762.html

你可能感兴趣的文章
flex的事件优先级与子类
查看>>
VirtualBox中的网络连接方式详解
查看>>
J实现时间格式的转换(附加对象的转换)
查看>>
前端学HTTP之URL
查看>>
SVG坐标系统及图形变换
查看>>
npm run build生成路径问题
查看>>
【入门】匈牙利算法+HNOI2006 hero超级英雄
查看>>
UOJ117:欧拉回路——题解
查看>>
求图的第K短路(A*算法与最短路的应用)
查看>>
Oracle EBS-SQL (WIP-4):检查检查成品标准作业是否勾选"固定"标识.sql
查看>>
std::vector的find();与erase();
查看>>
停止使用域名 boypay.net
查看>>
python-排序算法 冒泡和快速排序
查看>>
面向对象的三大特性之----------封装
查看>>
beanstalk源码剖析——网络框架
查看>>
第二节: 比较EF的Lambda查询和Linq查询写法的区别
查看>>
Django-Ajax
查看>>
DeepLearning.ai-Week1-Convolution+model+-+Step+by+Step
查看>>
通过GetManifestResourceStream加载文件出现错误提示“null值”对于“stream”无效[转]...
查看>>
C#读取XML节点
查看>>