博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Codeforces1142D
阅读量:5226 次
发布时间:2019-06-14

本文共 2016 字,大约阅读时间需要 6 分钟。

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 
#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
#define Pii pair
#define Plp pair< ll,Pii >#define Pip pair< int,Pii >#define Ppp pair< Pii,Pii >#define x first#define y secondtypedef 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\n",ans); return 0;}

转载于:https://www.cnblogs.com/RRRR-wys/p/10668310.html

你可能感兴趣的文章
:hover 鼠标同时触发两个元素变化
查看>>
go语言学习十三 - 相等性
查看>>
Idea 提交代码到码云(提交到github也大同小异)
查看>>
c#连接excel2007未安装ISAM解决
查看>>
Mono 异步加载数据更新主线程
查看>>
初识lua
查看>>
我是插件狂人,jDuang,jValidator,jModal,jGallery
查看>>
张季跃 201771010139《面向对象程序设计(java)》第四周学习总结
查看>>
如何解除循环引用
查看>>
android中fragment的使用及与activity之间的通信
查看>>
字典【Tire 模板】
查看>>
jquery的contains方法
查看>>
python3--算法基础:二分查找/折半查找
查看>>
Perl IO:随机读写文件
查看>>
Perl IO:IO重定向
查看>>
转:基于用户投票的排名算法系列
查看>>
WSDL 详解
查看>>
[转]ASP数组全集,多维数组和一维数组
查看>>
C# winform DataGridView 常见属性
查看>>
逻辑运算和while循环.
查看>>