【CQOI2016】手机号码

传送门:NKOJ3613
这是一道数位dp题。我最开始想用组合数学的方法(可以看看NKOJ1725)来做这道题,想了会儿不知道怎么写,才发现想复杂了。这里写图片描述
很明显,L~R区间内满足条件的号码个数满足前缀和性质,那么我们所要求的答案即dp(R)-dp(L-1)。
无脑地定了一个7维的状态,如下:

f[i][j][k][g3][i4][i8][if_greater_than_x]
表示当前填第i个数字(从低位到高位填),上一个填入的数字是j,当前填入的数字连续出现的次数k,是否已经出现了至少3位相同的连续数字,是否出现过4,是否出现过8,构造的数字是否已大于x。

显然,合法的号码用f状态表示为:

f[11][i][j][1][0][0][0]
f[11][i][j][1][1][0][0]
f[11][i][j][1][0][1][0]
(0<i<10,0<j<12)

统计答案时就把这些合法的方案都加上就行了。
状态定好了,转移方程也就出来了(我承认很丑):

if(j!=p)f[i+1][p][1][g3][i4|(p==4)][i8|(p==8)][if_greater(p,o,nub[i])]+=f[i][j][k][g3][i4][i8][o];
else f[i+1][p][k+1][g3|(k+1>2)][i4][i8][if_greater(p,o,nub[i])]+=f[i][j][k][g3][i4][i8][o];

这里没有管状态是否合法,直接就转移了,应该都能看懂吧,不懂的可以来怼我qwq(可私聊)。
以下是非常丑陋的代码:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值