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

浙公网安备 33010602011771号