题目背景
T1答案要mod1000000007(10^9+7),请重新提交,非常抱歉!
一天,智障的pipapi正在看某辣鸡讲义学程序设计。
题目描述
在讲义的某一面,他看见了一篇文章。这篇文章由英文字母(大小写均有)、数字、和空白字符(制表/空格/回车)构成。
pipapi想起了他最近刚刚学会写的Hello World程序。他非常好奇,这篇文章中,“HelloWorld”作为子序列到底出现过多少次呢?
由于papapi是个智障,大小写对于他而言毫无区别;因此,“hEllOWorLD”这样的子序列也是可以接受的。O和W之间的空格是也是可以少的;也就是说,“HelloWorld”是可以的。根据标程的意思,就是没有空格,不用考虑空格的情况。
两个子序列相同当且仅当它们每一个字符所在的位置都相同。
由于答案可能很大,请输出结果对1000000007(10^9+7)的余数。
输入输出格式
输入格式:
输入包含若干行。这些行的内容共同构成一篇文章。
文章以EOF(文件结尾)结束。
输出格式:
输出仅包含一个整数,表示这篇文章中“Hello World”出现的次数。
输入输出样例
HhEeLlLlOoWwOoRrLlDd
1536
Gou Li Guo Jia Sheng Si Yi Qi Yin Huo Fu Bi Qu Zhi River can feed people Also can race boats Hall Ellen Ok Words locked
273
说明
记n为输入的文章的长度(字符数)。
对于20%的数据,n <= 20。
对于50%的数据,n <= 500。
对于所有的数据,15 <= n <= 500000。
一道比较裸的dp题,把Helloworld拆成11个状态,"","h","he","hel"以此内推。处理文章。过滤掉所有没有用的字符,重新组成字符串。
用f[i][j]表示从第1个字符到第i个字符达到第j个状态的方案数。于是可以轻松地得出状态转移方程f[i][j] = f[i - 1][j] + (page[i] == sets[i])? (f[i - 1][j - 1]) : (0)(page表示处理后的文本串,sets[i]表示"helloworld"的第i个字符)。注意初值,在任何位置,组成空字符串的方案只有一种,所以f[i][0] = 1
Code
1 /** 2 * luogu.org 3 * Problem#2246 4 * Accepted 5 * Time:507ms 6 * Memory:17121k 7 */ 8 #include<iostream> 9 #include<cstdio> 10 #include<cctype> 11 #include<cstring> 12 #include<cstdlib> 13 #include<fstream> 14 #include<sstream> 15 #include<algorithm> 16 #include<map> 17 #include<set> 18 #include<queue> 19 #include<vector> 20 #include<stack> 21 using namespace std; 22 typedef bool boolean; 23 #define INF 0xfffffff 24 #define smin(a, b) a = min(a, b) 25 #define smax(a, b) a = max(a, b) 26 27 #define moder 1000000007 28 29 template<typename T>class Matrix{ 30 public: 31 T *p; 32 int lines; 33 int rows; 34 Matrix():p(NULL){ } 35 Matrix(int rows, int lines):lines(lines), rows(rows){ 36 p = new T[(lines * rows)]; 37 } 38 T* operator [](int pos){ 39 return (p + pos * lines); 40 } 41 }; 42 #define matset(m, i, s) memset((m).p, (i), (s) * (m).lines * (m).rows) 43 44 int n; 45 Matrix<int> f; 46 47 char page[500002]; 48 49 inline void init(){ 50 char x; 51 while(~(x = getchar())){ 52 if(x == 'h' || x == 'H') page[++n] ='h'; 53 else if(x == 'e' || x == 'E') page[++n] = 'e'; 54 else if(x == 'l' || x == 'L') page[++n] = 'l'; 55 else if(x == 'o' || x == 'O') page[++n] = 'o'; 56 else if(x == 'w' || x == 'W') page[++n] = 'w'; 57 else if(x == 'r' || x == 'R') page[++n] = 'r'; 58 else if(x == 'd' || x == 'D') page[++n] = 'd'; 59 } 60 f = Matrix<int>(n + 1, 11); 61 matset(f, 0, sizeof(int)); 62 } 63 64 char sets[12] = " helloworld"; 65 66 inline void solve(){ 67 for(int i = 0; i <= n; i++) f[i][0] = 1; 68 for(int i = 1; i <= n; i++){ 69 for(int j = 10; j > 0; j--){ 70 (f[i][j] += f[i - 1][j]) %= moder; 71 if(page[i] == sets[j]) (f[i][j] += f[i - 1][j - 1]) %= moder; 72 } 73 } 74 printf("%d", f[n][10]); 75 } 76 77 int main(){ 78 init(); 79 solve(); 80 return 0; 81 }