超长序列计数从值域入手(判定转状态)+分析dp状态数量:arc146_e

https://atcoder.jp/contests/arc146/tasks/arc146_e

Trick1 超长序列从值域入手(判定转状态)

通过绝对值的条件,其实我们可以从小到大放每个数。

对于两个相邻的同样数 i i i,他们之间必须放 i + 1 i+1 i+1

因此可以设计 d p [ i ] [ j ] [ 0 / 1 / 2 ] dp[i][j][0/1/2] dp[i][j][0/1/2] 表示前 i i i 个数,第 i i i 个有 j j j 个相邻的,左右两边有多少个为 i i i

Trick2 分析dp状态数量

此时状态是 O ( n 2 ) O(n^2) O(n2) 的。

但观察dp的转移过程很单一,相邻之间的转移相差也就1,而且第三维是类似一种层数的东西,只能从高层到低层。

此时大胆猜测状态数并不多。手玩一下可以发现,在第一、三维确定时,第二维的取值只有3种,然后记搜就完事了

int dfs(int i, int o, int k) {
   
	if(k<0 || k>=a[i]) return 0; 
	if(i<=1) return dp[i][o][k]; 
	if(dp[i][o].find(k)!=dp[i][o].end()) return dp[i][o][k]; 
	int tmp=0; 
	if(o==0) tmp=(dfs(i-1, 0, a[i]-k)+dfs(i-1, 1, a[i]-k)+dfs(i-1, 2, a[i]-k))%mo; 
	if(o==1) tmp=(dfs(i-1, 1, a[i]-k-1)+dfs(i-1, 2, a[i]-k-1)*2)%mo; 
	if(o==2) tmp=dfs(i-1, 2, a[i]-k-2); 
	return dp[i][o][k]=tmp*C(a[i]-1, a[i]-k-1)%mo; 
}

相关推荐

  1. 算法:状态压缩dp

    2023-12-25 14:04:01       14 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-25 14:04:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-25 14:04:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-25 14:04:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-25 14:04:01       18 阅读

热门阅读

  1. obs video-io.c

    2023-12-25 14:04:01       29 阅读
  2. 策略模式(Strategy)

    2023-12-25 14:04:01       36 阅读
  3. Transformer 模型设计的灵感

    2023-12-25 14:04:01       33 阅读
  4. 【题解】洛谷 P9183 [USACO23OPEN] FEB B

    2023-12-25 14:04:01       38 阅读
  5. git拉取远程分支到本地

    2023-12-25 14:04:01       36 阅读
  6. 【前端基础】uniapp、axios 获取二进制图片

    2023-12-25 14:04:01       43 阅读
  7. 使用Uniapp随手记录知识点

    2023-12-25 14:04:01       37 阅读
  8. DrmOpenWithType

    2023-12-25 14:04:01       32 阅读
  9. go语言基础 -- 字符串及其常用函数

    2023-12-25 14:04:01       33 阅读