• Codeforces 1150D DP


    题意:给你一个长度为n的字符串,有q次询问,每次询问会给字符串x的末尾添加一个字符y,或者删除字符串x末尾的字符,询问过后,要判断长度为n的字符串中是否有3个不重合的子序列,是这3个字符串。

    思路:设dp[i][j][j]为3个字符串的长度分别为i, j, k时,匹配的最靠前的位置。那么就枚举是通过哪个字符串转移即可,但是这样是O(n ^ 3)的。我们注意到每次询问过后某个字符串的长度最多改变1,那么我们可以只重新计算没改变的那两维就可以了。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 100010;
    int Next[maxn][26], dp[255][255][255], now[26];
    int a[4][300], tot[4];
    char s[maxn];
    int main() {
    	int n, m, x;
    	char op[5];
    	scanf("%d%d", &n, &m);
    	scanf("%s",s + 1); 
    	for (int i = 0; i < 26; i++) {
    		now[i] = n + 1;
    		Next[n + 1][i] = n + 1; 
    	}
    	for (int i = n; i >= 1; i--) {
    		for (int j = 0; j < 26; j++) {
    			Next[i][j] = now[j];
    		}
    		now[s[i] - 'a'] = i;
    	}
    	for (int i = 0; i < 26; i++)
    		Next[0][i] = now[i];
    	while(m--) {
    		scanf("%s", op + 1);
    		if(op[1] == '+') {
    			scanf("%d", &x);
    			scanf("%s", op + 1);
    			int y = op[1] - 'a';
    			a[x][++tot[x]] = y;
    			for (int i = (x == 1 ? tot[1] : 0); i <= tot[1]; i++)
    				for (int j = (x == 2 ? tot[2] : 0); j <= tot[2]; j++)
    					for (int k = (x == 3 ? tot[3] : 0); k <= tot[3]; k++) {
    						dp[i][j][k] = n + 1;
    					}
    			for (int i = (x == 1 ? tot[1] : 0); i <= tot[1]; i++)
    				for (int j = (x == 2 ? tot[2] : 0); j <= tot[2]; j++)
    					for (int k = (x == 3 ? tot[3] : 0); k <= tot[3]; k++) {
    						if(i) dp[i][j][k] = min(dp[i][j][k], Next[dp[i - 1][j][k]][a[1][i]]);
    						if(j) dp[i][j][k] = min(dp[i][j][k], Next[dp[i][j - 1][k]][a[2][j]]);
    						if(k) dp[i][j][k] = min(dp[i][j][k], Next[dp[i][j][k - 1]][a[3][k]]);
    					}
    		} else {
    			scanf("%d", &x);
    			tot[x]--;
    		}
    		if(dp[tot[1]][tot[2]][tot[3]] <= n) printf("YES
    ");
    		else printf("NO
    ");
    	}
    } 
    

      

  • 相关阅读:
    线程安全
    转 接口和抽象类 虚方法 有什么区别
    转 面向对象的三个基本特征
    转载 泛型
    遍历list,字典
    转 拉姆达表达式,委托、匿名方法、Lambda表达式的演进
    int byte转换
    委托,匿名方法
    带参数线程,不带参数线程
    const readonly
  • 原文地址:https://www.cnblogs.com/pkgunboat/p/10902579.html
Copyright © 2020-2023  润新知