【codevs1040】统计单词个数
这个题……之前一直没想好怎么记录字符串个数的问题,好讨厌字符串qwq
#include<iostream> #include<cstring> #include<cstdio> using namespace std; string ss,pi[7]; int n,p,k,s,sum[260][260],dp[260][260],len; void init() { for(int i=len-1;i>=0;i--)//预处理,枚举一段区间里到底有多少单词 for(int j=i;j>=0;j--) { string x=ss.substr(j,i-j+1); for(int l=1;l<=s;l++) { if(x.find(pi[l])==0)//如果开头是接着单词 { sum[j][i]=sum[j+1][i]+1;break;//直接令答案加一,退出,因为就算以j这个位置还有单词也会重复,所以就不用继续看这个位置 } else//否则答案和(j+1,i)这段区间答案一样 sum[j][i]=sum[j+1][i]; } } } int main() { scanf("%d",&n); while(n--) { memset(sum,0,sizeof(sum)); memset(dp,0,sizeof(dp)); scanf("%d%d",&p,&k); ss.clear(); string sss; while(p--) cin>>sss,ss+=sss; len=ss.length(); scanf("%d",&s); for(int i=1;i<=s;i++) cin>>pi[i]; init(); for(int i=1;i<=len;i++)//一次也没划分的答案,初始值 dp[i][1]=sum[0][i-1]; for(int i=2;i<=k;i++)//枚举划分次数 for(int j=i;j<=len;j++)//现在到了j位置 for(int l=i-1;l<j;l++)//枚举中间的断点 dp[j][i]=max(dp[j][i],dp[l][i-1]+sum[l][j-1]); printf("%d\n",dp[len][k]); } }