zoukankan      html  css  js  c++  java
  • Codeforces1142D

    Codeforces1142D

    做法:构建一个可以识别出合法串的自动机,然后就可以想办法在上边 dp 出答案。 首先,按照最直观的思路画一画这个自动机,找到每一个状态s如何推出它的后继t,然后通过状态的转移方式,找到等价的状态,想办法压缩这个自动机。我们令x的位数是d,ax是比x小的合法的数的数目,bx是位数是d的合法数中比x小的数的数目,cx是位数是d的合法数的数目。那么如果在x后添加一个数字s构成一个数字y,(ay = ax - bx + cx + cal(ax-bx+1,bx) + s), (cal(a,b))是从a开始到b在%11下循环求和。 这个式子的(ax-bx+cx)就是在计算x的这种位数中最后一个数字的编号,(cal(ax-bx+1,bx) + s)就是当前层比y小的数的个数,那么有(by = cal(ax-bx+1,bx) + s)(cy = cal(ax-bx+1,cx))。观察这个转移的式子,如果 ax+11 会导致 ay + 11,by, cy,如果 bx+11 会导致 ay - 11 + 55, by + 55, cy 如果cx + 11 会导致 ay + 11, by,cy + 55。观察可以知道 (ax,bx,cx) 在 %11 意义下等价,后继的数量种类也一致,转移是有等价性的,于是对于这个三元组(ax,bx,cx)我们建出11 * 11 * 11的状态转移图,而一个子串如果可以在这个图上完成匹配,他就是合法的。显然,对于个位置i如果它的最长匹配距离是A,那么答案加A,设(dp[i][j])表示以字符串的第i个位置为起点,自动机的节点j为起点,最长的匹配长度。就有(dp[i][j] = dp[i+1][nxt(j,s[i+1])] + 1),其中 (nxt(s,c)) 指状态s后添加一个字符c走到的新状态,需要注意的一点是,对于任意一种串的位置i和状态s,dp[i][s]至少为1!!复杂度(O(11^3 N))求解过程中需要理性取模。注意常数

    #include <bits/stdc++.h>
    #define rep(i,a,b) for(int i = (a); i <= (b); ++i)
    #define per(i,a,b) for(int i = (a); i >= (b); --i)
    #define pb push_back
    #define Pll pair<ll,ll>
    #define Pii pair<int,int>
    #define Plp pair< ll,Pii >
    #define Pip pair< int,Pii >
    #define Ppp pair< Pii,Pii >
    #define x first
    #define y second
    typedef long long ll;
    const int N = 100100;
    
    using namespace std;
    int cal(int a, int n) {
    	return (( (a+a+n-1)*n/2 )%11+11)%11;
    }
    int n, dp[2][11][11][11];
    char s[N];
    ll ans;
    
    int main() {
    	scanf(" %s",s+1); n = strlen(s+1);
    	int f = 0;
    	per(i, n, 1) {
    		int now = s[i] - '0', nx = s[i+1] - '0';
    		rep(a, 0, 10) rep(b, 0, 10) rep(c, 0, 10) {
    			dp[f][a][b][c] = 1;
    			if(i == n) continue;
    			if( (a+1)%11 <= nx ) continue;
    			int ta = (a - b + 11 + c + cal(a-b+1,b) + nx) % 11;
    			int tb = (cal(a-b+1,b) + nx) %11 ;
    			int tc = cal(a-b+1,c);
    			dp[f][a][b][c] = dp[f^1][ta][tb][tc] + 1;
    		}
    		if(now) ans += dp[f][now-1][now-1][9];
    		f ^= 1;
    	}
    	printf("%lld
    ",ans);
            return 0;
    }
    
  • 相关阅读:
    google说 老子 = I !
    昨日种种死 今日种种生
    设定Access数据库自增长字段初始值
    [c路历程]品品数组这杯茶
    爱上位运算
    .Net中的委托
    Jquery css函数用法(判断标签是否拥有某属性)
    记录几条简单的正则表达式
    ASP.NET MVC中DropDownList的使用
    C#如何获取object对象的属性值
  • 原文地址:https://www.cnblogs.com/RRRR-wys/p/10668310.html
Copyright © 2011-2022 走看看