首页 > 其他分享 >Public Easy Round #2 E. 2048

Public Easy Round #2 E. 2048

时间:2024-04-01 19:00:13浏览次数:16  
标签:kMod int sum kMaxN 2048 Easy bs Public ret

Description

pb 大师喜欢玩 2048。

pb 大师在一个 \(1\times n\) 的网格上玩 2048,初始 \(n\) 个格子都是空的。

游戏会进行若干轮,每轮将发生如下事件:

  1. 如果没有空位,游戏结束。否则随机一个 \(1\) 到 \(m\) 的数,随机到 \(i\) 的概率是 \(p_i\),再等概率随机一个空位,在空位中填入 \(2^i−1\)。

  2. 将所有数顺序不变移到最左侧。例如 _ _ x _ y z 会变成 x y z _ _ _

  3. 如果没有相邻相同的数,这一轮结束。否则从左往右最后一对相同的数变成他们的和以及一个空位,并且他的得分会加上产生的和,例如 x y y z _ _ 会变成 x 2y _ z _ _,并且 pb 大师会得到 \(2y\) 分,接下来回到第二步。

pb 大师想要知道:他的期望总得分是多少。

Solution

显然每次 1 操作之前所有已填的数构成一个前缀,所以那个选位置的操作是没意义的,于是每次相当于就是在栈的末尾添加一个数。

考虑 dp。

设 \(f_{i,j}\) 表示栈的大小为 \(i\),第一步填了 \(j\) 的期望得分。

这时会发现后面总共有三种可能:

  1. 后面比他小并且填到末尾。
  2. 后面能消成 \(j\) 然后与第一个 \(j\) 合并。
  3. 后面的第一个数比 \(j\) 大。

所以需要记 \(g_{i,j}\) 表示栈的大小为 \(i\),最终开头为 \(j\) 的期望得分,\(h_{i,j}\) 表示栈的大小为 \(i\),由空栈填成只有一个 \(j\) 的概率,\(s_{i,j}\) 表示栈的大小为 \(i\),由空栈填成只有一个 \(j\) 的期望得分。

那么可以得到转移方程:

\[\begin{aligned} h_{i,j}&=p_j+h_{i,j-1}\cdot h_{i-1,j-1}\\ s_{i,j}&=h_{i,j-1}s_{i-1,j-1}+h_{i-1,j-1}s_{i,j-1}+h_{i,j-1}h_{i-1,j-1}2^j\\ g_{i,j}&=s_{i,j}+h_{i,j}\left(\sum_{k=0}^{j-1}g_{i-1,k}+\sum_{k=j+1}^{m}{p_kf_{i-1,k}}\right)-s_{i,j}h_{i-1,j}\\ f_{i,j}&=\sum_{k=0}^{j-1}{g_{i-1,k}}+\sum_{k=j+1}^{m}{p_kf_{i-1,k}}+h_{i-1,j}\left(2^{j+1}+f_{i,j+1}\right)+s_{i-1,j} \end{aligned} \]

注意栈里的数可能达到 \(n+m\)。

时间复杂度:\(O\left(n(n+m)\right)\)。

Code

#include <bits/stdc++.h>

#define int int64_t

const int kMaxN = 2e3 + 5, kMod = 998244353;

int n, m;
int p[kMaxN * 2], pw[kMaxN * 2], f[kMaxN][kMaxN * 2], g[kMaxN][kMaxN * 2],
    h[kMaxN][kMaxN * 2], s[kMaxN][kMaxN * 2];
int pre[kMaxN * 2], suf[kMaxN * 2];

constexpr int qpow(int bs, int64_t idx = kMod - 2) {
  int ret = 1;
  for (; idx; idx >>= 1, bs = (int64_t)bs * bs % kMod)
    if (idx & 1) ret = (int64_t)ret * bs % kMod;
  return ret;
}

inline int add(int x, int y) { return (x + y >= kMod ? x + y - kMod : x + y); }
inline int sub(int x, int y) { return (x >= y ? x - y : x - y + kMod); }
inline void inc(int &x, int y) { (x += y) >= kMod ? x -= kMod : x; }
inline void dec(int &x, int y) { (x -= y) < 0 ? x += kMod : x; }

void dickdreamer() {
  std::cin >> n >> m;
  int sum = 0;
  for (int i = 1; i <= m; ++i) {
    std::cin >> p[i];
    inc(sum, p[i]);
  }
  sum = qpow(sum);
  for (int i = 1; i <= m; ++i) p[i] = 1ll * p[i] * sum % kMod;
  pw[0] = 1;
  for (int i = 1; i <= n + m + 1; ++i) pw[i] = add(pw[i - 1], pw[i - 1]);
  // get h, s
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n + m; ++j) {
      h[i][j] = add(p[j], 1ll * h[i][j - 1] * h[i - 1][j - 1] % kMod);
      s[i][j] =
          add(1ll * h[i][j - 1] * s[i - 1][j - 1] % kMod,
              add(1ll * h[i - 1][j - 1] * s[i][j - 1] % kMod,
                  1ll * h[i][j - 1] * h[i - 1][j - 1] % kMod * pw[j - 1] % kMod));
    }
  }
  // get f, g
  for (int i = 1; i <= n; ++i) {
    for (int j = 0; j <= n + m; ++j) {
      if (j) pre[j] = pre[j - 1];
      else pre[j] = 0;
      inc(pre[j], g[i - 1][j]);
    }
    for (int j = n + m; ~j; --j) {
      suf[j] = add(suf[j + 1], 1ll * p[j] * f[i - 1][j] % kMod);
      f[i][j] = add((j ? pre[j - 1] : (int)0), suf[j + 1]);
      g[i][j] = 1ll * h[i][j] * f[i][j] % kMod;
      inc(f[i][j], add(1ll * h[i - 1][j] * add(pw[j], f[i][j + 1]) % kMod, s[i - 1][j]));
      inc(g[i][j], 1ll * s[i][j] * sub(1, h[i - 1][j]) % kMod);
    }
  }
  int ans = 0;
  for (int i = 1; i <= m; ++i)
    inc(ans, 1ll * f[n][i] * p[i] % kMod);
  std::cout << ans << '\n';
}

int32_t main() {
#ifdef ORZXKR
  freopen("in.txt", "r", stdin);
  freopen("out.txt", "w", stdout);
#endif
  std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);
  int T = 1;
  // std::cin >> T;
  while (T--) dickdreamer();
  // std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
  return 0;
}

标签:kMod,int,sum,kMaxN,2048,Easy,bs,Public,ret
From: https://www.cnblogs.com/Scarab/p/18109168

相关文章

  • 海康Ehome2.0与5.0设备接入EasyCVR视频汇聚平台时的配置区别
    安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防视频监控的能力,也具备接入AI智能分析的......
  • 智慧安防监控EasyCVR视频调阅和设备录像回看无法自动播放的原因排查与解决
    智慧安防监控EasyCVR视频管理平台能在复杂的网络环境中,将前端设备统一集中接入与汇聚管理。国标GB28181协议视频监控/视频汇聚EasyCVR平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、云存储等丰富的......
  • EasyRecovery15最新破解版注册机激活码
    EasyRecovery是一款在市场上广受欢迎的数据恢复软件,具备许多强大而实用的功能。首先,它支持多种媒体类型的数据恢复,包括硬盘驱动器、存储设备、光学媒体、多媒体/移动设备以及RAID系统等。这意味着,无论数据是从哪种类型的设备中丢失的,都有机会通过EasyRecovery进行恢复。在使用......
  • gpg: Can't check signature: No public key,及gpg原理
    gpg--verifyopenresty-1.21.4.3.tar.gz.ascopenresty-1.21.4.3.tar.gzgpg:Signaturemade2023-11-0405:31:16+0000UTCgpg:usingRSAkeyB550E09EA0E98066gpg:Can'tchecksignature:Nopublickey解决办法gpg--keyserverhkp://keyserver.......
  • easyexcel合并策略
    1、行合并@Slf4jpublicclassExcelRowHandlerimplementsRowWriteHandler{/***起始行索引*/privateIntegerstartRowIndex=0;/***结束行索引*/privateIntegerendRowIndex;privateSet<Integer>mergeColSe......
  • 探索 Go 的 Fan-Out/Fan-In 模式:让并发更 easy
    探索Go的Fan-Out/Fan-In模式:让并发更easy原创 GoOfficialBlog GoOfficialBlog 2024-03-2921:03 中国香港 听全文学习如何利用Go语言的并发性能,使用扇出/扇入模式。探索这种模式如何在Go应用程序中简化复杂的并发任务。Introduction并发在Go中可以......
  • 使用easyPoi的动态列导出
    项目背景:有一个导出excel的需求,要求导出部分固定列和部分动态列,固定列使用字段写死,动态列使用list集合存放成果展示:思路:简单说就是一个行转列的处理1.使用easypoi的注解方式进行导出,固定列部分使用@Excel标注2.动态列使用一个List集合,用@ExcelCollection标注,里面的......
  • 视频汇聚/安防监控/智能监控EasyCVR平台设备录像接口调用汇总
    AI视频智能分析/视频监控管理平台EasyCVR能在复杂的网络环境中(专网、内网、局域网、广域网、公网等),支持设备通过4G、5G、WIFI、有线等方式接入,并将设备进行统一集中接入与视频汇聚管理,经平台接入的视频流能实现多格式分发,包括:RTMP、RTSP、HTTP-FLV、WebSocket-FLV、HLS、WebRTC、w......
  • [oeasy]python0012_程序写错了怎么办
    运行python文件_报错处理_NameError......
  • EasyExcel库来读取指定Excel文件中的数据
    FileexcelFile=newFile(path);if(!excelFile.exists()){thrownewException("Thespecifiedexcelfiledoesnotexistatpath:"+path);}//使用EasyExcel读取文件......