思路比较简单的一道题。

用的五维 dp,看到二维和三维的 dp 直接膜了 orz。

正文开始。

分析

不难看出 dp。

因为 \(b_i\) 的值只与 \(a_{i-1},a_i,a_{i+1}\) 有关,所以我们定义 \(b_i\) 被 \(a_{c_1},a_{c_2},...a_{c_p}\) 满足为在这些 \(a\) 中最大的一项恰好为 \(b_i\)。

用 \(dp_{i,j,0/1,0/1,z}\) 来表示此状态下的方案数。

其中:

  • \(i\) 表示当前处于第 \(i\) 项。
  • \(j\) 表示当前这一项选择 \(j\)。
  • \(1/0\) 表示 \(b_i\) 是否被 \(a_{i-1},a_i\) 满足。
  • \(1/0\) 表示 \(b_0\) 是否被 \(a_0,a_1\) 满足。
  • \(z\) 表示 \(a_0\) 选择 \(z\)。

显然,\(a_i\) 的最大值就是 \(\min(b_{i-1},b_i,b_{i+1})\),又因为 \(b_i\le10\),所以 \(a_i\) 的最大值也是 \(10\)。

状态转移方程比较复杂。

如果 \(i>1\),那么我们需要枚举 \(a_i\) 和 \(a_{i-1}\)。

这时候存在两种情况:

  1. \(b_i\) 被 \(a_i,a_{i-1}\) 满足,此时应该更新 \(dp_{..,..,1,..,..}\) 的值。
  2. \(b_i\) 不被 \(a_i,a_{i-1}\) 满足,此时应该更新 \(dp_{..,..,0,..,..}\) 的值。

注意:在选择 \(a_i\) 的时候,\(b_{i-1}\) 必须被 \(a_{i-2},a_{i-1},a_i\) 满足,原因显然。

但当 \(i=1\) 时,应该单独讨论,因为 \(a_1\) 的选择会影响到 dp 数组的第 \(4\) 项,而 \(i\ge2\) 则不会。思路跟 \(i\ge2\) 的情况类似,不再赘述。

最后统计答案时,我们有几种情况:

  • \(dp_{n-1,x,1,1,y}\),因为此时 \(b_{n-1}\) 和 \(b_0\) 已经被满足,而其它的 \(b\) 也都被满足,直接加上即可。
  • \(dp_{n-1,x,0,1,y}\) 当 \(b_{n-1}\le y\) 时可以相加,因为 \(a\) 数组是环形的。
  • \(dp_{n-1,x,1,0,y}\) 当 \(b_0\le x\) 时可以相加,原因同上。

最后,记得取模。

AC Code

臭长臭长的代码 qwq。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N = 1010;
  4. const int MOD = 1e9 + 7;
  5. int n;
  6. int dp[N][11][2][2][11], b[N], am[N];
  7. int st;
  8. inline int nxt (int idx) {
  9. return ((idx + 1) % n);
  10. }
  11. inline int pre (int idx) {
  12. return ((idx - 1 + n) % n);
  13. }
  14. int m (int x) {
  15. if (x < MOD) return x;
  16. return x - MOD;
  17. }
  18. int main () {
  19. ios::sync_with_stdio(false);
  20. cin.tie(0);cout.tie(0);
  21. cin >> n;
  22. for (int i = 0;i < n;i++) cin >> b[i];
  23. for (int i = 0;i < n;i++) am[i] = min(b[pre(i)], min(b[i], b[nxt(i)]));
  24. for (int i = 0;i <= am[0];i++) if (i < b[0]) dp[0][i][0][0][i] = 1; else dp[0][i][1][1][i] = 1;
  25. for (int x = 0;x <= am[0];x++) for (int st = 0;st <= 1;st++) for (int j = 0;j <= am[1];j++) {
  26. if (j < b[1] && x < b[1]) {
  27. if (j < b[0]) dp[1][j][0][st][x] += m(dp[0][x][0][st][x] + dp[0][x][1][st][x]), dp[1][j][0][st][x] = m(dp[1][j][0][st][x]);
  28. else dp[1][j][0][1][x] += m(dp[0][x][0][st][x] + dp[0][x][1][st][x]), dp[1][j][0][1][x] = m(dp[1][j][0][1][x]);
  29. }
  30. else {
  31. if (j < b[0]) dp[1][j][1][st][x] += m(dp[0][x][0][st][x] + dp[0][x][1][st][x]), dp[1][j][1][st][x] = m(dp[1][j][1][st][x]);
  32. else dp[1][j][1][1][x] += m(dp[0][x][0][st][x] + dp[0][x][1][st][x]), dp[1][j][1][1][x] = m(dp[1][j][1][1][x]);
  33. }
  34. }
  35. for (int i = 2;i < n;i++) {
  36. int p = i - 1;
  37. for (int x = 0;x <= am[0];x++) for (int st = 0;st <= 1;st++) {
  38. for (int j = 0;j <= am[i];j++) {
  39. for (int z = 0;z <= am[p];z++) {
  40. if (j < b[i] && z < b[i]) {
  41. if (j < b[p]) dp[i][j][0][st][x] += dp[p][z][1][st][x];else dp[i][j][0][st][x] += m(dp[p][z][0][st][x] + dp[p][z][1][st][x]);
  42. dp[i][j][0][st][x] = m(dp[i][j][0][st][x]);
  43. }
  44. else {
  45. if (j < b[p]) dp[i][j][1][st][x] += dp[p][z][1][st][x];
  46. else dp[i][j][1][st][x] += m(dp[p][z][0][st][x] + dp[p][z][1][st][x]);
  47. dp[i][j][1][st][x] = m(dp[i][j][1][st][x]);
  48. }
  49. }
  50. }
  51. }
  52. }
  53. int ans = 0;
  54. for (int x = 0;x <= am[0];x++) for (int i = 0;i <= am[n - 1];i++) {
  55. ans += dp[n - 1][i][1][1][x]; ans = m(ans);
  56. if (i >= b[0]) ans += dp[n - 1][i][1][0][x];
  57. if (x >= b[n - 1]) ans += dp[n - 1][i][0][1][x];
  58. ans = m(ans);
  59. }
  60. cout << ans << endl;
  61. return 0;
  62. }

P8810 [蓝桥杯 2022 国 C] 数组个数 题解的更多相关文章

  1. P8796 [蓝桥杯 2022 国 AC] 替换字符

    题面 给定一个仅含小写英文字母的字符串 \(s\) 和 \(m\) 次操作,每次操作选择一个区间 \([l_i,r_i]\) 将 \(s\) 的该区间中的所有字母 \(x_i\) 全部替换成字母 \( ...

  2. 2016年蓝桥杯B组C/C++决赛题解

    2016年第七届蓝桥杯B组C/C++决赛题解 2016年蓝桥杯B组C/C++决赛题目(不含答案) 1.一步之遥 枚举解方程,或者套模板解线性方程 #include<bits/stdc++.h&g ...

  3. 2015年蓝桥杯B组C/C++决赛题解

    2015年第六届蓝桥杯B组C/C++决赛题解 点击查看2015年第六届蓝桥杯B组C/C++国赛题目(不含答案)     1.积分之迷 三重循环 枚举A,B,C的值,如果满足两个条件:3个A + 7个B ...

  4. 2018年蓝桥杯B组C/C++决赛题解

    2018年第九届蓝桥杯B组C/C++决赛题解 点击查看2018年蓝桥杯B组C/C++决赛题目(不含答案) 1.换零钞 ok 枚举 设x表示1元钱的个数,y表示2元钱的个数,z表示5元钱的个数 x+21 ...

  5. 2018年蓝桥杯A组C/C++决赛题解

    2018年第九届蓝桥杯A组C/C++决赛题解 点击查看视频题解 点击查看2018年蓝桥杯A组C/C++决赛题目(不含答案) 1:三角形面积 画个图,求三角形面积,可以用外接长方形 - 其他多余区域面积 ...

  6. 第十届蓝桥杯省赛JavaB组个人题解

    前言 以下的第十届蓝桥杯Java B组省赛的题目题解只是我个人的题解,提供一些解题思路,仅作参考,如有错误,望大家指出,不甚感激,我会及时更改. 试题 A: 组队 ----- 答案:490 [问题描述 ...

  7. 2017年蓝桥杯B组C/C++决赛题解

    2017年蓝桥杯B组C/C++决赛题目(不含答案) 1.36进制 ok 求36进制,类比二进制转10进制,36^3 + 36^2 + 36^1 + 36^0 2.磁砖样式 ok dfs搜索 我自己写的 ...

  8. 蓝桥杯 算法训练 ALGO-50 数组查找及替换

    算法训练 数组查找及替换   时间限制:1.0s   内存限制:512.0MB 问题描述 给定某整数数组和某一整数b.要求删除数组中可以被b整除的所有元素,同时将该数组各元素按从小到大排序.如果数组元 ...

  9. Java实现 蓝桥杯 算法训练 删除数组零元素

    算法训练 删除数组零元素 时间限制:1.0s 内存限制:512.0MB 提交此题 从键盘读入n个整数放入数组中,编写函数CompactIntegers,删除数组中所有值为0的元素,其后元素向数组首端移 ...

  10. Java实现 蓝桥杯 算法训练 寻找数组中最大值

    算法训练 寻找数组中最大值 时间限制:1.0s 内存限制:512.0MB 提交此题 问题描述 对于给定整数数组a[],寻找其中最大值,并返回下标. 输入格式 整数数组a[],数组元素个数小于1等于10 ...

随机推荐

  1. Java商城网站系统设计与实现(带源码)

    基于Java的商城网站系统设计与实现 功能介绍 平台采用B/S结构,后端采用主流的Springboot框架进行开发,前端采用主流的Vue.js进行开发. 整个平台包括前台和后台两个部分. 前台功能包括 ...

  2. 流计算中kafka的OffsetReset策略

    朋友的公司做的是西南某边境省份网红新能源车的数据处理,由于新能源车的火爆,从年初从现在,数据量已经翻番.但与此同时,服务器却没有多少增加.无奈之下,只能暂时将kafka的数据存储时间由之前的1天改为6 ...

  3. Python实现XSS扫描

    利用Python代码实现XSS检测 import requests # HTML转换实体字符 def str_html(source): result = "" for c in ...

  4. 文心一言 VS 讯飞星火 VS chatgpt (26)-- 算法导论5.1 1题

    一.证明:假设在过程 HIRE-ASSISTANT 的第 4 行中,我们总能决定哪一个应聘者最佳.则意味着我们知道应聘者排名的全部次序. 文心一言: 证明: 假设在过程 HIRE-ASSISTANT ...

  5. 又爱又恨的 Microsoft Edge!

    早在< 使用码云同步谷歌 Chrome 浏览器书签 · 语雀>中就吐槽过 win7 下安装 Microsoft Edge 一大堆错误代码的问题,一直都折腾不出个所以然.然而公司的 PC 一 ...

  6. 云原生时代Go最受欢迎Web开源框架Gin原理与实战

    @ 目录 概述 定义 特点 概览导图 使用 快速入门 HTTP 方法使用 参数获取 参数绑定 自定义日志输出 自定义中间件 路由组 HTML渲染 设置和获取Cookie XML.YAML.ProtoB ...

  7. 一篇文章带你入门HBase

    本文已收录至Github,推荐阅读 Java随想录 微信公众号:Java随想录 目录 HBase特性 Hadoop的限制 基本概念 NameSpace Table RowKey Column Time ...

  8. 【Netty】Netty部分源码分析(启动流程,EventLoop,accept流程,read流程)

    源码分析 Netty源码中调用链特别长,且涉及到线程切换等步骤,令人头大:) 1 启动剖析 我们就来看看 netty 中对下面的代码是怎样进行处理的 //1 netty 中使用 NioEventLoo ...

  9. vue前端预览pdf并加水印、ofd文件,控制打印、下载、另存,vue-pdf的使用方法以及在开发中所踩过的坑合集

    根据公司的实际项目需求,要求实现对pdf和ofd文件的预览,并且需要限制用户是否可以下载.打印.另存pdf.ofd文件,如果该用户可以打印.下载需要控制每个用户的下载次数以及可打印的次数.正常的预览p ...

  10. celery笔记八之数据库操作定时任务

    本文首发于公众号:Hunter后端 原文链接:celery笔记八之数据库操作定时任务 前面我们介绍定时任务是在 celery.py 中的 app.conf.beat_schedule 定义,这一篇笔记 ...