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

P1026 统计单词个数

时间:2020-03-14 19:51:45      阅读:52      评论:0      收藏:0      [点我收藏+]

标签:题意   处理   class   std   字符   状态   ring   div   out   

题意:给出p串字符(每串都是20个字母)   给出k ,k表示总共可以分成几部分;

   给出词典,这个词典最多包含6个单词,

   求如何分,能够得到最多单词;

   注:每份中包含的单词可以部分重叠。当选用一个单词之后,其第一个字母不能再用

思路:很明显,这道题应该用dp解法;

首先,我们先将p串字符连成一串

我们需要处理两部分;

第一部分:预处理:我们先预处理出每一个区间范围内的单词个数;

第二部分:dp【i】【j】表示前i个字符分成k块

      然后便是dp的代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int m;
 4 string s,dic[10],ch;
 5 int num[205][205],dp[205][45];
 6 bool judge(int l,int r)
 7 {
 8     string ss=s.substr(l,r-l+1);//取出l到r的字符串
 9     for(int i=1;i<=m;i++)
10         if(ss.find(dic[i])==0)
11             return true;//find返回的是第一个下标
12     return false;
13 }
14 int main()
15 {
16     ios::sync_with_stdio(false);
17     int p,k;
18     cin>>p>>k;
19     s+=\0;//为了s的下标从1开始
20     for(int i=1;i<=p;i++){
21         cin>>ch;
22         cout<<ch<<endl;
23         s+=ch;
24         cout<<s<<endl;
25     }
26     cin>>m;
27     for(int i=1;i<=m;i++)
28         cin>>dic[i];
29     int len=s.length()-1;
30     for(int i=len;i>=1;i--)//预处理单词数,i为右端点,j为左端点
31     {
32         for(int j=i;j>=1;j--)
33         {
34             num[j][i]=num[j+1][i];
35             if(judge(j,i))num[j][i]++;
36         }
37     }
38     dp[0][0]=0;
39     for(int i=1;i<=len;i++)//边界状态,到i只分成一块即1-i的单词数
40         dp[i][1]=num[1][i];
41     for(int i=1;i<=len;i++)//枚举右端点,左端点都是max(1,分的段数)
42         for(int j=1;j<=k&&j<=i;j++)//枚举分成了几段
43             for(int l=j;l<i;l++)//枚举左端点与右端点之间的点
44                 dp[i][j]=max(dp[i][j],dp[l][j-1]+num[l+1][i]);
45     printf("%d\n",dp[len][k]);
46     return 0;
47 }

转载自:https://blog.csdn.net/qq_40942372/article/details/86699259

P1026 统计单词个数

标签:题意   处理   class   std   字符   状态   ring   div   out   

原文地址:https://www.cnblogs.com/pangbi/p/12493702.html

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