小美的子序列
小美在n行m列的本子上写了许多字母,她会在每一行中找出一个字母,然后组成一个字符串。
小美想知道,组成的字符串中是否存在至少一个字符串包含 "meituan" 子序列。
输入描述
第一行输入2个整数n,m(1<=n,m<=1000) 。
接下来n行,每行输入一个长度为m的字符串表示小美写下的字母。
输出描述
若存在至少一个字符串包含 "meituan" 子序列,则输出 "YES",否则输出 "NO"。
示例1
输入
3 3
abc
def
ghi
输出
NO
说明
显然并不能找到meituan子序列。
示例2
输入
8 2
nm
ex
it
td
ul
qu
ac
nt
输出
YES
说明
第1行选择第2个字母。
第2行选择第1个字母。
第3行选择第1个字母。
第4行选择第1个字母。
第5行选择第2个字母。
第6行选择第2个字母。
第7行选择第1个字母。
第8行选择第1个字母。
组成字符串"meitluan",其中存在"meituan"子序列。
当然,第6行选第1个字母且第5行选第1个字母组成的字符串"meituqan"中也存在"meituan"子序列。
思路:
i在这里的含义是第i个输入的字符串,j为 meituqan 这八个字母的其中之一
我们定义一个二维数组 ext[i][j] 为字母j是否在第i个字符串中存在,然后遍历所有输入的字符串,标记所有的ext
接着我们定义dp[i][j] 为 在前i个字符串中,结尾为j的字母是否被满足,
当dp[i-1][j] = true时,意味着在之前一个字符串中就已经满足了以j为结尾的 meituqan 字符串了,所以 dp[i][[j]可以直接继承他的状态
当dp[i-1][j]!=true时,意味着先前没有满足 以j为结尾的 meituqan 字符串,那么 dp[i][j]的状态就取决于 dp[i-1][j-1] && ext[j][j] 即(上一个输入的字符串是否满足 j前面那个字符为结尾的字符串)&& (在第i个输入的字符串中是否存在j)
我们可以得出转移方程
dp[i][j] = dp[i-1][j] || ( ext[i][j] && dp[i-1][j-1] )
在初始化阶段 dp[i][0] 的状态完全由ext[i][0]决定,因为此时 j 只有一个字符串,没有前面的状态,出现输入的字符串中就说明他是true,否则为false
代码
import java.util.Scanner;
import java.util.Stack;
public class Main {
private static final int MAXN = 10005;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
sc.nextLine();
String[] s = new String[n+1];
for(int i=1;i<=n;i++){
s[i] = sc.nextLine();
}
boolean[][] ext = new boolean[MAXN][7]; // 字母j在i行是否存在
boolean[][] dp = new boolean[MAXN][7];
for(int i = 1;i<=n;i++){
for(int j=1;j<=m;j++){
char c = s[i].charAt(j-1);
int t = decode(c);
if(t>=0){
ext[i][t] = true;
}
}
}
for(int i=1;i<=n;i++){
for(int j=0;j<7;j++){
if(j==0){
if(ext[i][j]){
dp[i][j] = true;
}else{
dp[i][j] = false;
}
continue;
}
// dp[i][j] = dp[i-1][j];
if(ext[i][j]){
dp[i][j] = dp[i-1][j-1] || dp[i-1][j];
}else{
dp[i][j] = dp[i-1][j];
}
}
}
System.out.println(dp[n][6]? "YES":"NO");
}
public static int decode(char c){
switch (c){
case 'm':
return 0;
case 'e':
return 1;
case 'i':
return 2;
case 't':
return 3;
case 'u':
return 4;
case 'a':
return 5;
case 'n':
return 6;
}
return -1;
}
}