CODEVS 1040统计单词个数
来源:互联网 发布:金融数据分析师待遇 编辑:程序博客网 时间:2024/06/13 18:26
对于这种序列型的动态规划,常用的处理方案是利用W[l][r]表示从l到r的序列所能得到的最大目标函数值。
由于本题还有一个划分次数的限制,因此,容易想到的是把常用方案改写成
W[l][r][limit]这种形式。
但是显然这种形式的维护效率很低。实际上,经过仔细思考,要计算出最后的答案W[0][end][limit],并不需要求出所有的W值,而只需要求出limit为0的时候的全部W[l][r]和l为0的时候的全部W[r][limit]即可。
/*1040 统计单词个数 2001年NOIP全国联赛提高组时间限制: 1 s空间限制: 128000 KB题目等级 : 黄金 Gold题解题目描述 Description给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个)。要求将此字母串分成k份(1<k<=40),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠。当选用一个单词之后,其第一个字母不能再用。例如字符串this中可包含this和is,选用this之后就不能包含th)(管理员注:这里的不能再用指的是位置,不是字母本身。比如thisis可以算做包含2个is)。单词在给出的一个不超过6个单词的字典中。要求输出最大的个数。输入描述 Input Description第一行为一个正整数(0<n<=5)表示有n组测试数据每组的第一行有二个正整数(p,k)p表示字串的行数;k表示分为k个部分。接下来的p行,每行均有20个字符。再接下来有一个正整数s,表示字典中单词个数。(1<=s<=6)接下来的s行,每行均有一个单词。输出描述 Output Description每行一个整数,分别对应每组测试数据的相应结果。样例输入 Sample Input11 3thisisabookyouareaoh4isaoksab12 3thisisabookyouareaohthisisabookyouareaoh4isaoksab样例输出 Sample Output7*/#include<iostream>#include<algorithm>#include<cstdio>#include<string>#include<cstring>#include<vector>using namespace std;/*通过DP获得以下两个数组两个数组(以下的r都视为超尾指针)1.W[l][r] l到r这一段的最多能有多少个单词计算算法 :W[r][r] = 0;W[l - 1][r] = W[l][r] + 1(如果存在text[l]开头的当初的话)2.V[r][t] 从头部到r的这一段,经过t次划分,存在多少个单词计算算法:V[r][0] = W[0][r],V[0][t] = 0;V[r][t] = MAX(...V[m][t - 1] + W[m][r]...)(t <= m < r)*/int W[250][250];int V[250][50];string text,buf;vector<string>word;void input(string & text,int p){ //输入字符串 p行 text.clear(); word.clear(); for (int i = 0; i < p; i++){ cin >> buf; text += buf; } int Num; cin >> Num; for (int i = 0; i < Num; i++){ cin >> buf; word.push_back(buf); }}bool check(int l,int r){ //检查是否存在字符串 int i,j; buf.resize(r - l); copy(text.begin() + l, text.begin() + r, buf.begin()); for (i = 0; i < word.size(); i++){ int len = word[i].size(); if (len > buf.size())continue; for (j = 0; j < len; j++){ if (word[i][j] != buf[j])break; } if (j == len)return true; } return false;}void CalW(int len){ //计算W的值 int l,r; for (r = len; r > 0; r--){ W[r][r] = 0; for (l = r - 1; l >= 0; l--){ W[l][r] = W[l + 1][r]; if (check(l,r))W[l][r]++; } }}void CalV(int len,int Tmax){ int r, t, i; memset(V, 0, sizeof(V)); for (r = 1; r <= len; r++)V[r][0] = W[0][r]; for (t = 1; t <= Tmax; t++){ for (r = 1; r <= len; r++){ for (i = t; i < r; i++){ V[r][t] = max(V[r][t], V[i][t - 1] + W[i][r]); } } }}int main(void){ int i, j, T; cin >> T; for (int TT = 0; TT < T; TT++){ cin >> i >> j; input(text,i); CalW(i * 20); CalV(i * 20,j - 1);//分成j个部分,说明被分了j - 1次 cout << V[text.size()][j - 1] << endl; } return 0;}
0 0
- CODEVS 1040 统计单词个数
- Codevs 1040 统计单词个数
- CODEVS 1040统计单词个数
- codevs天梯 统计单词个数
- 1040 统计单词个数
- (昨天的)codevs 天梯 统计单词个数 dp
- wiki-1040统计单词个数
- 【wikioi】1040 统计单词个数
- wikioi 1040 统计单词个数
- wiki 1040 统计单词个数
- CODE[VS] 1040 统计单词个数
- vc 统计单词个数
- 统计单词个数
- 统计单词个数
- 统计单词个数
- 统计单词个数
- 统计单词个数
- 统计单词个数
- problem
- 单片机控制三极管
- 判断10-105之间有多少个素数,并输出所有素数。
- Picasso,Glide,Fresco 对比
- mybatis环境搭建及创建一个mybatis连接
- CODEVS 1040统计单词个数
- 随想1
- find命令及文件包的安装
- Oracle分组函数之ROLLUP
- 不再贩卖「情怀」的锤子手机
- Mask-RCNN技术解析
- 17
- ubuntu16.04 ns2安装教程
- windows下配置redis集群,启动节点报错:createing server TCP listening socket *:7000:listen:Unknown error