题目链接
这道题写了两个DP
第一个sum[i][j]
预处理i到j中所含有的字符串数量
从后往前判断,便于判断第i个字符是否用上写一个check函数
如果第i个字符用上了x.find(a[i])==0
返回true
第二个dp算最大值
f[i][j]
表示前i
个字符分为j
段的最大值
f[i][j]=max(f[i][j],f[k][j-1]+sum[k+1][i])
(j-1<k<i)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=210;
string a[10];
int sum[N][N]={0};
int f[N][N];
string s;
int n,m,K;
bool check(int l,int r)
{
string x=s.substr(l,r-l+1);
for(int i=1;i<=n;i++)
if(x.find(a[i])==0)
return true;
return false;
}
int main()
{
cin>>n>>K;
s=" ";
while(n--)
{
string _;
cin>>_;
s+=_;
}
m=s.size()-1;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=m;i>=1;i--)
{
for(int j=i;j>=1;j--)
{
sum[j][i]=sum[j+1][i];
if(check(j,i))
sum[j][i]++;
}
f[i][1]=sum[1][i];
}
for(int i=1;i<=m;i++)
for(int j=1;j<=K;j++)
for(int k=j;k<i;k++)
{
f[i][j]=max(f[i][j],f[k][j-1]+sum[k+1][i]);
}
cout<<f[m][K]<<endl;
}