wiki 1040 统计单词个数

来源:互联网 发布:最新网络广告法 编辑:程序博客网 时间:2024/05/22 14:07

动态规划:其中f[i][j]表示字符序列前i个字符分成j份时,单词出现的次数,sum[i][j]表示字符序列中从第i个字符到第j个字符之间出现词典中的单词的总个数。状态转移方程如下:

f[i][j] = max{f[u][j-1], sum[u+1][i]} 其中j-2 <= u <= i-1

sum[i][j] = sum[i+1][j] + temp 其中temp = (从字符串第i个字符开头,能匹配上词典中的任意一个单词 ? 1 : 0)

#include <iostream>#include <string.h>#include <stdio.h>using namespace std;int p,k,n;string c;string w[7];int f[210][50],sum[210][210];int makesum (int a, int b){    if(sum[a][b]!=-1) return sum[a][b];    int temp = 0;    for(int i = 0; i < n; i++){        if(w[i].length()<=b-a+1 && w[i]==c.substr(a,w[i].length())) {            temp = 1;            break;        }    }    sum[a][b] = temp + (a<b ? makesum(a+1, b) : 0);    return sum[a][b];}int main(int argc, const char * argv[]){    int t;    scanf("%d", &t);    while (t > 0) {        t--;        scanf("%d %d", &p, &k);        for(int i = 0; i < p; i++){            string temp;            cin >> temp;            c += temp;        }        scanf("%d", &n);        for(int i = 0; i < n; i++){            cin >> w[i];        }        memset(f, 0, sizeof(f));        memset(sum, -1, sizeof(sum));        for(int i = 0; i < c.length(); i++){            f[i][1] = makesum(0, i);        }        for(int i = 2; i <= k; i++){            for(int j = i-1; j < c.length(); j++){                int tempmax = 0;                for(int u = i-2; u < j; u++){                    tempmax = (tempmax < (f[u][i-1]+makesum(u+1, j)) ? f[u][i-1]+makesum(u+1, j) : tempmax);                }                f[j][i] = tempmax;            }        }        printf("%d\n", f[c.length()-1][k]);    }}


0 0
原创粉丝点击