LuoguP2875
分析:
首先在读 题 完毕后,发现暴力的做法也不是很好做,再回想关于字符串的种种问题,发现没有什么字符串的模型可以使用,尽管模仿 电子字典 似乎可行,但仔细一想,对蓝题这么做是在没有必要,并且确实想不出一个可行的方案前进,所以向 dp 方面想。
具体方案:
既然有这个方向,就继续思考,设一个简单的状态,
显而易见的,如果枚举到
我们思考一下,如果不删这个字母,肯定是因为加上了它,可以与前面的某些字母组成一个单词,比如
所以策略就自然而然跳了出来,我们可以枚举每一个单词,看看以选的这个字母为结尾时,需要多少个字母才能组出来(比如上面的例子,字母是
接下来看如何求
代码如下,仅供参考(代码中单词是
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n, l, f[305], len[605];
char c[305];
string s[605];
int aaa(int x, int y, int &le){
int j = len[y], sum = 0;
le = -1;
for(int i = x; i >= 1; i --){
if(c[i] == s[y][j])
j --;
else
sum ++;
if(j == 0){
le = i;
break;
}
}
return sum;
}
signed main(){
scanf("%lld%lld%s", &n, &l, c + 1);
for(int i = 1; i <= n; i ++){
cin >> s[i];
len[i] = s[i].size();
s[i] = "0" + s[i];
}
f[0] = 0;
for(int i = 1; i <= l; i ++){
f[i] = f[i - 1] + 1;
for(int j = 1; j <= n; j ++){
int le;
int sum = aaa(i, j, le);
if(le != -1)
f[i] = min(f[i], f[le - 1] + sum);
}
}
printf("%lld", f[l]);
return 0;
}
祝各位大佬刷题愉快。