zoukankan      html  css  js  c++  java
  • [TJOI 2018]游园会

    题意:求NOI的合法串。。。

    思路:

    首先这个似乎和后缀自动机没关系(话说TJ不考后缀自动机??),其实就是一个\(DP\)\(DP\),考虑如果不看兑奖串就是一个LCS,当出现时多记一维即可。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 100010;
    const int mod = 1e9+7;
    int bit[maxn];
    int t[maxn][3];
    int dp[21];
    int g[21];
    int f[2][maxn][3][3];
    int ans[21];
    int n,m;
    int k;
    int a[21];
    char s[21];
    int nw = 1;
    int nxt;
    inline int read() {
    	int q=0,f=1;char ch = getchar();
    	while(!isdigit(ch)) {
    		if(ch=='-') f = -1;ch = getchar();
    	}
    	while(isdigit(ch)) {
    		q=q*10+ch-'0';ch = getchar();
    	}
    	return q*f;
    }
    inline void upd(int &x,int y) {
    	x += y;
    	if(x >= mod) x -= mod;
    }
    
    int main () {
    	m = read(),n = read();
    	scanf("%s",s+1);
    	int lim = (1 << n);
    	for(int i = 1;i < lim; ++i) {
    		bit[i] = bit[i >> 1] + (i & 1);
    	}
    	for(int i = 1;i <= n; ++i) {
    		if(s[i] == 'N') a[i] = 0;
    		if(s[i] == 'O') a[i] = 1;
    		if(s[i] == 'I') a[i] = 2;
    	}
    	for(int k = 0;k < lim; ++k) {
    		for(int i = 1;i <= n; ++i) {
    			dp[i] = dp[i - 1] + (k >> (n - i) & 1);
    		}
    		for(int i = 0;i < 3; ++i) {
    			for(int j = 1;j <= n; ++j) {
    				if(i == a[j]) {
    					g[j] = dp[j - 1] + 1;
    				}
    				else g[j] = max(g[j - 1],dp[j]);
    			}
    			for(int j = 1;j <= n; ++j) {
    				if(g[j] == g[j - 1] + 1) {
    					t[k][i] |= 1 <<n - j;
    				}
    			}
    		}
    	}
    	f[0][0][0][0] = 1;
    	for(int i = 1;i <= m; ++i) {
    		swap(nw,nxt);
    		for(int j = 0;j < lim; ++j) {
    			memset(f[nxt][j],0,sizeof(f[nxt][j]));
    		}
    		if(i <= 2) {
    			for(int j = 0;j < lim; ++j) {
    				for(int k = 0;k < 3; ++k) {
    					for(int l = 0;l < 3; ++l) {
    						if(f[nw][j][k][l])
    						for(int r = 0;r < 3; ++r) {
    							upd(f[nxt][t[j][r]][l][r],f[nw][j][k][l]);
    						}
    					}
    				}
    			}
    		}
    		else {
    			for(int j = 0;j < lim ;++j) {
    				for(int k = 0;k < 3; ++k) {
    					for(int l = 0;l < 3; ++l) {
    						if(f[nw][j][k][l]) {
    							int res = f[nw][j][k][l];
    							for(int r = 0;r < 3; ++r) {
    								if(!k && l == 1 && r == 2) continue;
    								upd(f[nxt][t[j][r]][l][r],res);
    							}
    						}
    					}
    				}
    			}
    		}
    	}
    	for(int i = 0;i < lim; ++i) {
    		for(int j = 0;j < 3; ++j) {
    			for(int k = 0;k < 3 ; ++k) {
    				upd(ans[bit[i]],f[nxt][i][j][k]);
    			}
    		}
    	}
    	for(int i = 0;i <= n; ++i) printf("%d\n",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    css样式的六种选择器
    css 颜色表示法
    css 文本设置
    “http”和“https”的区别是什么?优缺点是什么?
    Httpclient
    接口认证:Bearer Token(Token 令牌)
    哪个参数用来区分请求来自客户(手机)端还是服务器(PC)端?
    常用的HTTP响应头
    Http 请求头包含哪些信息?
    单例集合的体系
  • 原文地址:https://www.cnblogs.com/akoasm/p/9437767.html
Copyright © 2011-2022 走看看