[ARC 058 - E]Iroha and Haiku
解题步骤
首先可以发现题目范围非常小,尤其是\(X,Y,Z\),所以考虑类似状压、数位dp、双向搜索等算法。
官方题解中给的是数位dp,那我这里就讲讲状压了
对于\(N \leq 40\),很明显不能对其进行状压并且没意义,那么对于\(X,Y,Z\)呢?因为题目要求连续一段数满足要求,且\(X+Y+Z \leq 17,a_i \geq 1\),故只用考虑连续一段长度不超过17的的区间是否满足要求即可。
但是对于具体数值怎么状压呢?我们发现因为和不超过\(X+Y+Z\),所以我们可以对当前第\(i\)位前一段和不超过\(X+Y+Z\)的区间的每一个数\(a_j\)通过\(2^{a_j}\)表示,同时按顺序依次乘\(2^{a_i}\),如此既没改变相对顺序,又表示出数值,实现如下:
int tot = (1 << X + Y + Z) - 1;
int s = ((msk << j) | (1 << j - 1)) & tot;
/*
tot为全集
j为枚举当前位填入的元素
msk即为前一个状态元素集合
s则为加上当前元素j后的元素集合
*/
到这里,状压思路已经很清晰了,最后一个难点为判定满足条件。因为我们对于状压状态,发现一段前缀的和在不断位移的操作下变成了某一个元素在\(msk\)对应的单个\(1\),故目标可表示为(1<<X-1)|(1<<X+Y-1)|(1<<X+Y+Z-1),对于当前集合判断包不包含目标集合,如果包含,满足条件,反之不满足。
int targ = (1 << X - 1) | (1 << X + Y - 1) | (1 << X + Y + Z - 1), tot = (1 << X + Y + Z) - 1;
int s = ((msk << j) | (1 << j - 1)) & tot;
if ((s & targ) != targ)
dp[i][s] = (dp[i][s] + dp[i - 1][msk]) % mod;
/*
targ为目标集合
dp[i][msk]表示考虑第i位,前一段和不超过X+Y+Z的区间为msk的情况下,有多少种情况不满足条件
*/
最后做个解释,为什么dp[i][msk]要表示不满足条件的区间。因为对于初始状态,不满足条件的区间都由dp[0][0]演化而来,而满足条件的区间千变万化,可以从很多种情况转移,不好把握。
最终实现
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 45, TN = 17;
const LL mod = 1e9 + 7;
LL dp[N][1 << TN];
int X, Y, Z, n;
LL ans;
inline LL power(LL a, LL k) //可要可不要,直接O(N)把ans乘一遍也只是40
{
LL ret = 1;
while (k)
{
if (k & 1)
ret = ret * a % mod;
a = a * a % mod;
k >>= 1;
}
return ret;
}
int main()
{
scanf("%d%d%d%d", &n, &X, &Y, &Z);
dp[0][0] = 1;
ans = power(10ll, n);
int targ = (1 << X - 1) | (1 << X + Y - 1) | (1 << X + Y + Z - 1), tot = (1 << X + Y + Z) - 1;
//targ:目标集合 tot:全集
for (int i = 1; i <= n; i++)
for (int msk = 0; msk <= tot; msk++)
for (int j = 1; j <= 10; j++)
{
int s = ((msk << j) | (1 << j - 1)) & tot;
//加入当前元素后集合
if ((s & targ) != targ) //不满足条件
dp[i][s] = (dp[i][s] + dp[i - 1][msk]) % mod;
}
//dp第一层循环一定是1~n,因为第i位是该dp的一个阶段,所有第i层的状态都依赖于上一层
for (int msk = 0; msk <= tot; msk++)
ans = (ans - dp[n][msk] + mod) % mod;
printf("%lld", ans);
return 0;
}
[ARC 058 - E]Iroha and Haiku的更多相关文章
- 和風いろはちゃんイージー / Iroha and Haiku (ABC Edition) (水水)
题目链接:http://abc042.contest.atcoder.jp/tasks/abc042_a Time limit : 2sec / Memory limit : 256MB Score ...
- [Arc058E] Iroha and Haiku
[Arc058E] Iroha and Haiku 题目大意 问有多少\(n\)个数的正整数序列,每个数在\([1,10]\)之间,满足存在\(x,y,z,w\)使得\(x\to y-1,y\to z ...
- Solution -「ARC 058C」「AT 1975」Iroha and Haiku
\(\mathcal{Description}\) Link. 称一个正整数序列为"俳(pái)句",当且仅当序列中存在连续一段和为 \(x\),紧接着连续一段和为 \(y ...
- ARC 058
所以为啥要写来着........... 链接 T1 直接枚举大于等于$n$的所有数,暴力分解判断即可 复杂度$O(10n \log n)$ #include <cstdio> #inclu ...
- AtCoder Regular Contest
一句话题解 因为上篇AGC的写的有点长……估计这篇也短不了所以放个一句话题解方便查阅啥的吧QwQ 具体的题意代码题解还是往下翻…… ARC 058 D:简单容斥计数. E:用二进制表示放的数字,然后状 ...
- AtCoder Regular Contest 058
这个应该是第一场有英文的atcoder吧??不过题解却没有英文的... 从前往后慢慢做... C こだわり者いろはちゃん / Iroha's Obsession 数据范围这么小,直接暴力 #inclu ...
- AtCoder 瞎做
目录 ARC 058 E - 和風いろはちゃん / Iroha and Haiku 题意 题解 技巧 代码 ARC 059 F - バイナリハック / Unhappy Hacking 题意 题解 技巧 ...
- AtCoder-arc058(题解)
A - こだわり者いろはちゃん / Iroha's Obsession(暴力) 题目链接 题目大意: 给你 \(k\) 个个位数字和一个数字 \(n\) ,要求找到一个大于等于n的数字,使得不出现 \ ...
- csp退役前的做题计划1(真)
csp退役前的做题计划1(真) 因为我太菜了,所以在第一次月考就会退役,还是记录一下每天做了什么题目吧. 任务计划 [ ] Z算法(Z Algorithm) 9.28 [x] ARC061C たくさん ...
- 【AtCoder】ARC058
ARC058 C - こだわり者いろはちゃん / Iroha's Obsession 暴力一个个枚举是最简单的方式 #include <bits/stdc++.h> #define fi ...
随机推荐
- 4G模组AT指令 | MQTT应用指南!
今天,老师傅讲的是关于4G模组AT指令之MQTT应用,以4G模组Air780E为例: 一.MQTT 协议简介 1.1 MQTT 概述 MQTT 是一种轻量级的消息传输协议,旨在在物联网(IoT)应用中 ...
- 2024-11-20:交替子数组计数。用go语言,给定一个二进制数组 nums, 如果一个子数组中的相邻元素的值都不相同,我们称这个子数组为交替子数组。 请返回数组 nums 中交替子数组的总数。 输
2024-11-20:交替子数组计数.用go语言,给定一个二进制数组 nums, 如果一个子数组中的相邻元素的值都不相同,我们称这个子数组为交替子数组. 请返回数组 nums 中交替子数组的总数. 输 ...
- (Python基础教程之十四)Python将tuple开箱为变量或参数
Python示例将N元素元组或序列开箱缩为N个变量的集合.将元组开箱缩为变量的 Python示例. 1. Python开箱元组示例 可以使用简单的赋值操作将任何序列(或可迭代)开箱缩为变量.唯一的要求 ...
- mysql之编译安装
在CentOS7中编译安装MySQL 5.7.29 一.依赖包安装 yum install gcc gcc-c++ ncurses ncurses-devel cmake bison -y 二.下载源 ...
- Blazor 组件库 BootstrapBlazor 中Modal组件介绍
组件说明 Model组件是一个模态框组件,可以弹出一个对话框,适合需要定制性更大的场景. 它的样子如下: 其html代码为: <div class="modal-content&quo ...
- LGR-204-Div.2
Contest link 质量不错的比赛. A 比较明显的题,贪心往下做就可以. #include <bits/stdc++.h> using i64 = long long; const ...
- ZCMU-1156
思路: 要改变的是一个范围的情况,所以正常情况下会超时. 查阅后知道应该用一个叫做树状数组的结构. 查阅和树状数组的后续情况 这个也不错 注意: 我没怎么看懂,可能没太仔细看. 树状数组当中存在的是前 ...
- ZCMU-1051
比较来说不太难其实,当然找到一定的公式这与前面的1033相识,都会用到f(i,j)=f(i-1,j)+f(i-1,j-1) 我们可以先从小部分看出来,一层可以整体或者两部分,在面对第i层看前面i-1层 ...
- Vue第三方插件
1.滚动条 vuescroll 引入插件 - 官网 <script src="https://unpkg.com/vuescroll"></script> ...
- 鸿蒙UI布局实战 —— 个人中心页面开发
1.前言 接下里我们将开启"鸿蒙UI布局系列"的学习,第一站:学习线性布局(Row/Column)+ 弹性布局(Flex) 在展开学习前,先上一个实战demo--开发一个个人中心页 ...