NOIP 2001 统计单词个数 解题报告
比较难做的DP吧,首先要预处理一个w[i][j],代表从i~j之间存在的单词个数,嗯。。
然后f[j][i] = max(f[l][i - 1] + w[l + 1][j]) (i<l<j)
代码如下:
#include <stdio.h> #include <string.h> #include <stdlib.h> char str[202]; char sub[6][201]; int len[6]; int d[201], w[201][201]; int f[201][41]; int main(int argc, char **argv) { int i, j, l; int n, m, k; scanf("%d%d", &n, &k); for(i = 0; i < n; i++){ scanf("%s", &str[1 + 20 * i]); } n *= 20; scanf("%d", &m); for(i = 0; i < m; i++){ scanf("%s", sub[i]); len[i] = strlen(sub[i]); } for(i = 1; i <= n; i++){ for(j = 0; j < m; j++){ if(strncmp(&str[i], sub[j], len[j]) == 0 && (d[i] == 0 || d[i] > len[j])){ d[i] = len[j]; } } } for(i = 1; i <= n; i++){ for(j = i; j <= n; j++){ w[i][j] = w[i][j - 1]; for(l = i; l <= j; l++){ w[i][j] += d[l] == (j - l + 1) ? 1 : 0; } } } for(i = 1; i <= k; i++){ for(j = i; j <= n; j++){ for(l = i - 1; l < j; l++){ if(f[j][i] < f[l][i - 1] + w[l + 1][j]){ f[j][i] = f[l][i - 1] + w[l + 1][j]; } } } } printf("%d\n", f[n][k]); return 0; }