标签: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