首页 > 其他分享 >[ARC 058 - E]Iroha and Haiku

[ARC 058 - E]Iroha and Haiku

时间:2025-01-18 17:11:02浏览次数:1  
标签:满足条件 d% 17 int 状压 ARC 058 Iroha dp

传送门

解题步骤

首先可以发现题目范围非常小,尤其是\(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;
}

标签:满足条件,d%,17,int,状压,ARC,058,Iroha,dp
From: https://www.cnblogs.com/keysky/p/18678620

相关文章

  • 科普文:算法和数据结构系列【死磕字典树:字典树的升级版三叉树Ternary Search Tree优化
    概叙科普文:算法和数据结构系列【死磕字典树:来一个英文字母游戏】-CSDN博客科普文:算法和数据结构系列【高效的字符串检索结构:字典树Trie树原理、应用及其java示例代码解读】-CSDN博客‌原理‌:Trie树利用字符串之间的公共前缀来减少不必要的字符串比较,从而提高查询效率。每个......
  • 工具 | StarCodeSecurity
    0x00简介StarCodeSecurity是一款图形化的代码审计工具。下载地址:StarCodeSecurity下载:StarCodeSecurity下载0x01功能说明支持对规则进行增删改查审计文件后缀审计路径关键字禁止审计路径关键字支持java、php、net项目审计注:仅供安全研究与学习之用,若将工......
  • ElasticSearch metrics aggregations(度量聚合)
    目录metricsaggregations(度量聚合)avg(平均聚合)脚本(script)值脚本(valuescript)缺失的值(missingvalue)weighted_avg(加权平均聚合)例子脚本(script)缺失的值(missingvalues)boxplot(箱线图聚合)语法脚本(script)箱线图的值(通常)是近似值压缩(compression)缺失的值cardina......
  • ElasticSearch 桶(bucket)聚合
    目录桶(bucket)聚合adjacency_matrix聚合使用Limitationsauto_date_histogram(自动间隔的日期直方图聚合)键(key)间隔(interval)时区(timezone)脚本参数minimum_interval缺失的值children聚合composite(复合聚合)值的来源(valuesource)terms(词项)histogram(直方图)datehistog......
  • ElasticSearch Aggregations(聚合)
    目录Aggregations(聚合)构建聚合值的来源Aggregations(聚合)聚合框架有助于提供基于搜索查询的聚合数据。它基于被称为聚合(aggregations)的简单构建块,可以组合这些块来构建复杂的数据摘要。聚合可以被看作是在一组文档上构建分析信息的工作单元。执行的上下文定义了这个文档......
  • AtCoder Regular Contest 058 [ARC058] F - Unhappy Hacking
    题意:有三种操作,在右边添加0/1或删除最右边的数(空字符串无操作)给出操作数\(N\),字符串\(s\),问有多少种方法经过\(N\)次操作后得到字符串\(S\)思路最开始在想三维dp,虽然发现了性质,但是没想到很好的用法重要性质:答案与字符串内容无关,仅与字符串长度有关定义\(f_{i,j}\)为操作\(i......
  • [ARC108F] Paint Tree
    前言复习什么的就留到下周了,顺便把格式调好现在把每日一练打了差不多今天补了一下午的\(\rm{T2}\),终于还是被码力问题击碎了,不过也还好这道题是模拟赛\(\rm{T3}\)吉司机线段树和左偏树都只能明天搞了,明天把\(\rm{C}\)打了开摆思路首先那几个\(\rm{subtask}\)......
  • Arc B570:英特尔的中端“战锤”能否撼动 200 美元显卡市场?
    前言:新晋“挑战者”,中端GPU市场一夜变天?“200美元显卡市场已经死气沉沉?”或许在2024年底之前,真相并非如此。继ArcB580以出乎意料的高性价比拿下口碑与销量后,英特尔又锻造了一把新的“战锤”——ArcB570。它的目标非常明确:在NVIDIA和AMD低端产品线尚未更新、空当......
  • elasticsearch之数据聚合
    **聚合(aggregations)**可以让我们极其方便的实现对数据的统计、分析、运算。例如:什么品牌的手机最受欢迎?这些手机的平均价格、最高价格、最低价格?这些手机每月的销售情况如何?实现这些统计功能的比数据库的sql要方便的多,而且查询速度非常快,可以实现近实时搜索效果。聚合的种......
  • post、get请求(查询字符串参数)将对象拼接为地址栏请求参数new URLSearchParams
    constparams=newURLSearchParams({param1:'value1',param2:'value2'}).toString();该方法可将param1和param2拼接为param1=value1&param2=value2实例consturl='https://example.com/api/resource';constparams=newURLSearchP......