洛谷 P1026 统计单词个数

题意

给出一个长度不超过 200的由小写英文字母组成的字母串(该字串以每行 20 个字母的方式输入,且保证每行一定为 2 个)。要求将此字母串分成 k 份,且每份中包含的单词个数加起来总数最大。

每份中包含的单词可以部分重叠。当选用一个单词之后,其第一个字母不能再用。例如字符串 this 中可包含 this 和 is,选用 this 之后就不能包含 th。

单词在给出的一个不超过 6 个单词的字典中。

要求输出最大的个数。

做法

动态规划加上暴力枚举,数组 f [ i ] [ j ] 表示前 i 个字符分成 j 段的最多单词数。

代码

#include<bits/stdc++.h>
using namespace std;
int p,k;
string c;
string q;
int s;
string d[7];
int f[205][45];

int cnt(int l,int r)
{
    int ans=0;
    for(int i=l;i<=r;++i)
    {
        for(int j=1;j<=s;++j)
        {
            int os=d[j].size();
            if(os>r-i+1) continue;
            string iu;
            for(int jj=0;jj<os;++jj)
              iu+=q[i+jj];
            if(iu==d[j])  
            {
               ++ans;
               break;
            }
        }
    }
    return ans;
}
int main() 
{ 
    //freopen("msquare.in","r",stdin);\
    //freopen("msquare.out","w",stdout);
    cin>>p>>k;
    for(int i=1;i<=p;++i)
        cin>>c,q+=c;
    int n=q.size();
    //cout<<q<<" "<<n<<endl;
    q = "0"+q;
    cin>>s;    
    for(int i=1;i<=s;++i)
        cin>>d[i];
    for (int j = 1; j <= n; ++j)
        f[0][j] = -1e9;
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=i&&j<=k;++j)
        {
            for (int ii=0; ii < i; ++ii)
                f[i][j] = max(f[i][j], f[ii][j-1]+cnt(ii+1, i));
        }
        for (int j = i+1; j <= k; ++j)
            f[i][j] =  -1e9;
    }       
    cout<<f[n][k]<<endl;
    return 0; 
}

 

posted @ 2022-02-13 10:52  LikC1606  阅读(57)  评论(0)    收藏  举报