码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2014-10-25 22:55:45      阅读:438      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   io   os   ar   使用   for   strong   

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

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;
}

 

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

标签:style   blog   color   io   os   ar   使用   for   strong   

原文地址:http://www.cnblogs.com/zoniony/p/4050947.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!