统计单词个数 题解
2023-09-15 22:58:20
发布于:广东
16阅读
0回复
1点赞
dp,就是。
按本题的要求,我们首先要实现一个函数,代表在目标的字符串中有多少个单词。我在这里用的是直接用二维数组推一遍,当做初始化提前把函数执行了。
作者这里使用的是倒推。
我们想,每次插入一个字母,如果在当前位置上不能构成字母,那和不加这个字母有什么区别呢?如果在当前位置上能构成字母,也是在不插入这个字母的基础上单词量,于是,我们可以先设
为第位到第位所包含的单词数,初始时把他赋值为,再判断他可不可以构成单词,如果可以, 就。
核心代码
for(int j=s.size(); j>=1; j--)
for(int i=j; i>=1; i--)
{
word_num[i][j]=word_num[i+1][j];
string temp=s.substr(i,j-i+1);
for(int k=1; k<=num; k++)
{
if(temp.find(word[k])==0)
{
word_num[i][j]++;
break;
}
}
// cout<<"word_num["<<i<<"]["<<j<<"] = "<<word_num[i][j]<<endl;
}
dp部分:
和 [NOIP2000 提高组] 乘积最大 很像,可以设为前个字符分成段可以得到的最大单词数,再依次枚举第段的起点进行状态转移,就可以了。
状态转移方程:
好难打,跪求一个免费的赞
而最后的答案为。
第一条转移方程是当只分份的时候,那肯定全选,所以字母量为。
第二条转移方程是当份数和字母数相同,即每一份只有一个字母,所以直接从上一个状态加上当前的价值就可以了。
第三条转移方程是枚举开头,其他的也不用多说了。
注意事项:
1.由于函数使用的是倒推,所以循环要从大到小。
2.一个字母只能对应一个单词的开头,所以一旦找到单词符合,直接break
。
3.在第三条转移方程中, 循环的上限为,是因为执行的过程中可能份数过多,字母不够分。
最后祝大家早日
拿下AC!!!
AC代码
#include<iostream>
#include<cstring>
using namespace std;
string word[16];
int num;
int word_num[210][210];
int f[210][50];
int n,m;
void work()
{
cin>>n>>m;
memset(f,0,sizeof(f));
string s=" ";
for(int i=1; i<=n; i++)
{
string temp;
cin>>temp;
s+=temp;
}
cin>>num;
for(int i=1; i<=num; i++)
cin>>word[i];
for(int j=s.size(); j>=1; j--)
for(int i=j; i>=1; i--)
{
word_num[i][j]=word_num[i+1][j];
string temp=s.substr(i,j-i+1);
for(int k=1; k<=num; k++)
{
if(temp.find(word[k])==0)
{
word_num[i][j]++;
break;
}
}
// cout<<"word_num["<<i<<"]["<<j<<"] = "<<word_num[i][j]<<endl;
}
// for(int i=1; i<=n*20; i++)
// for(int j=i; j<=n*20; j++)
// cout<<"word_num["<<i<<"]["<<j<<"] = "<<word_num[i][j]<<endl;
for(int i=1; i<=m; i++)
f[i][i]=f[i-1][i-1]+word_num[i][i];
for(int i=1; i<s.size(); i++)
f[i][1]=word_num[1][i];
for(int i=1; i<s.size(); i++)
for(int j=1; j<=m&&j<i; j++)
for(int k=j; k<=i; k++)
f[i][j]=max(f[i][j],f[k-1][j-1]+word_num[k][i]);
cout<<f[s.size()-1][m]<<endl;
// for(int i=1; i<=n*20; i++)
// for(int j=0; j<=m; j++)
// cout<<"f["<<i<<"]["<<j<<"] = "<<f[i][j]<<endl;
return;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
// int t;
// cin>>t;
// while(t--)
work();
return 0;
}
这里空空如也
有帮助,赞一个