RQNOJ 302 PID302 / [NOIP2001]统计单词个数(区间dp)
2014-04-16 19:28
489 查看
区间dp,状态转移公式是:dp[i][j] = max{dp[i][j], dp[i-1][k]+sum[k+1][j] };预处理出来所有的i到j有多少种情况。枚举每个区间。预处理有点麻烦。
题目描述
给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个)。要求将此字母串分成k份(1<k<=40),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠。当选用一个单词之后,其第一个字母不能再用。例如字符串this中可包含this和is,选用this之后就不能包含th)。
单词在给出的一个不超过6个单词的字典中。
要求输出最大的个数。
输入格式
第一行有二个正整数(p,k)
p表示字串的行数;
k表示分为k个部分。
接下来的p行,每行均有20个字符。
再接下来有一个正整数s,表示字典中单词个数。(1<=s<=6)
接下来的s行,每行均有一个单词。
输出格式
一个整数,结果。
题目描述
给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个)。要求将此字母串分成k份(1<k<=40),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠。当选用一个单词之后,其第一个字母不能再用。例如字符串this中可包含this和is,选用this之后就不能包含th)。
单词在给出的一个不超过6个单词的字典中。
要求输出最大的个数。
输入格式
第一行有二个正整数(p,k)
p表示字串的行数;
k表示分为k个部分。
接下来的p行,每行均有20个字符。
再接下来有一个正整数s,表示字典中单词个数。(1<=s<=6)
接下来的s行,每行均有一个单词。
输出格式
一个整数,结果。
#include <algorithm> #include <iostream> #include <stdlib.h> #include <string.h> #include <iomanip> #include <stdio.h> #include <string> #include <queue> #include <cmath> #include <stack> #include <map> #include <set> #define eps 1e-8 #define M 1000100 #define LL __int64 //#define LL long long #define INF 0x3f3f3f3f #define PI 3.1415926535898 using namespace std; const int maxn = 2010; int dp[maxn][50]; char str[maxn]; char st[20][20]; char s[maxn]; int cnt[maxn][maxn]; int sum[maxn][maxn]; int main() { int n, m; while(cin >>n>>m) { memset(dp, 0 , sizeof(dp)); for(int i = 0; i < n; i++) { cin >>s; for(int j = i*20, k = 0; k < 20; k++, j++) str[j] = s[k]; } int t; cin >>t; for(int i = 0; i < t; i++) cin >>st[i]; int len = strlen(str); for(int i = 0; i < len; i++) { int mi = len; for(int j = 0; j < t; j++) { int kk = 0; if(str[i] == st[j][0]) { for(kk = 0; kk < strlen(st[j]) && (i+kk) < len; kk++) { if(str[i+kk] != st[j][kk]) break; } if(kk == strlen(st[j])) mi = min(mi, i+kk-1); } } for(int j = mi; j < len; j++) cnt[i][j] = 1; } for(int i = 0; i < len; i++) sum[len-1][i] = cnt[len-1][i]; for(int i = len-2; i >= 0; i--) { for(int j = i; j < len; j++) { if(cnt[i][j]) sum[i][j] = sum[i+1][j]+1; else sum[i][j] = sum[i+1][j]; } } for(int i = 0; i < len; i++) dp[1][i] = sum[0][i]; for(int i = 2; i <= m; i++) for(int j = 0; j < len; j++) for(int k = i-2; k < j; k++) dp[i][j] = max(dp[i][j], dp[i-1][k]+sum[k+1][j]); cout<<dp[m][len-1]<<endl; } return 0; }
相关文章推荐
- RQNOJ PID302 / [NOIP2001]统计单词个数 (动态规划)
- RQNOJ-302-统计单词个数--区域dp
- ACM 94. [NOIP2001] 统计单词个数(划分dp)
- noip2001统计单词个数
- 洛谷P1026&NOIP2001 统计单词个数
- noip2001 统计单词数
- codevs1040 统计单词个数(区间dp+划分dp)
- NOIP2001 统计单词个数
- 【NOIP2011】统计单词个数 划分性dp*2
- 【NOIP2001】统计单词个数
- NOIP2001 统计单词个数 rabin-karp哈希
- noip2001 统计单词个数 (动态规划-划分)
- NOIP提高组2001-统计单词个数
- [洛谷luogu] [NOIP2001T3]统计单词个数 (DP)
- 洛谷 P1026 [NOIP2001 T3] 统计单词个数
- 【动规递推】【NOIP2001】统计单词个数
- noip2001-统计单词个数2008.11.5
- [抄]NOIP 2001 统计单词个数
- 数目nullRQNOJ-302-统计单词个数--区域dp
- 统计单词个数 (区间DP)