首页 > 代码库 > 【字符串处理+动规】单词的划分

【字符串处理+动规】单词的划分

【字符串处理+动规】单词的划分

Time Limit: 1000MS
Memory Limit: 2560KB

有一个很长的由小写字母组成字符串。为了便于对这个字符串进行分析,需要将它划分成若干个部分,每个部分称为一个单词。出于减少分析量的目的,我们希望划分出的单词数越少越好。你就是来完成这一划分工作的。

输入格式
第一行,一个字符串。(字符串的长度不超过100)
    第二行一个整数n,表示单词的个数。(n<=100)
    第3~n+2行,每行列出一个单词。

输出格式
    一个整数,表示字符串可以被划分成的最少的单词数。

样例输入
realityour
5
real
reality
it
your
our

样例输出
2
(原字符串可拆成real+it+your或reality+our,由于reality+our仅为两个部分,因此最优解为2,另外注意,单词列表中的每个单词都可以重复使用多次,也可以不用)

状态:f[i]表示到f[i]结尾的最少划分次数

状态转移方程:if(f[i]==0)f[i]=f[m]+1;else f[i]=min(f[i],f[m]+1);

这题数据很弱

跟饥饿的牛一样以区间为状态

# include<stdio.h># include<cstring># include<vector># include<iostream># include<algorithm>using namespace std;const int maxn=1000;vector<int>q[300];char st[maxn],dp[maxn][maxn];int f[maxn];int check(int a,int b,int c){    if(c-dp[q[a][b]][0]+1<=0)return 0;    for(int i=1,j=c-dp[q[a][b]][0]+1;i<=dp[q[a][b]][0]&&j>=1;i++,j++)    if(dp[q[a][b]][i]!=st[j])return 0;    return 1;}int main(){    scanf("%s\n",st+1);     st[0]=strlen(st+1);    int n;scanf("%d",&n);    for(int i=1;i<=n;i++){        scanf("%s",dp[i]+1);        dp[i][0]=strlen(dp[i]+1);        q[dp[i][dp[i][0]]].push_back(i);    }    for(int i=1;i<=st[0];i++)    for(int j=0;j<q[st[i]].size();j++)    if(check(int(st[i]),j,i)){    int m=i-dp[q[st[i]][j]][0];    if(f[i]==0)f[i]=f[m]+1;    else f[i]=min(f[i],f[m]+1);    }    printf("%d",f[st[0]]);    return 0;}

 

【字符串处理+动规】单词的划分