首页 > 其他分享 >2024初秋集训——提高组 #21

2024初秋集训——提高组 #21

时间:2024-10-01 10:23:10浏览次数:1  
标签:frac 21 int 2024 MAXN 初秋 ans id dp

B. 网格游走

题目描述

你在一个 \(r\times c\) 的网格图的 \((1,1)\) 处。每个格子上都有一个箭头和计时器,一开始,箭头等概率地指向右/下方,计时器上等概率地显示 \([0,p]\) 中的一个实数。当计时器归零时,箭头指向的方向会翻转,即向右变成向下,向下变成向右,并且计时器会重置为 \(p\)。

你在一个格子上时,可以:

  • 如果当前格子箭头向右,且右边有格子,那么可以走到右边的格子。
  • 如果当前格子箭头向下,且下边有格子,那么可以走到下边的格子。
  • 等待计时器归零。

你的移动不需要时间,只有等待需要。你只能观察到当前格子的箭头和计时器状态。假设你按照最优方式操作,求到达 \((r,c)\) 的所需期望时间。

思路

令 \(dp_{i,j}\) 表示从 \((i,j)\) 开始到达 \((r,c)\) 的期望时间。

有两种转移:

  • 若 \(i<r,j<c\)。我们令 \(a=\min(dp_{i+1,j},dp_{i,j+1}),b=\max(dp_{i+1,j},dp_{i,j+1})\)。有 \(\frac{1}{2}\) 的概率一开始箭头指向 \(a\),但还有 \(\frac{1}{2}\) 的概率指向 \(b\),假设当前计时器为 \(x\),并令 \(v=\min(b-a,p)\):

    • 若 \(x\le v\),那么我们肯定会选择等待并走 \(a\),期望为 \((a+\frac{v}{2})\cdot \frac{v}{p}\),\(a+\frac{v}{2}\) 为这种情况的期望时间,\(\frac{v}{p}\) 是这种情况的概率。

    • 若 \(x>v\),那么我们会直接走 \(b\),期望为 \(b\cdot \frac{p-v}{p}\)。

    • 所以我们有转移 \(dp_{i,j}=\frac{a}{2}+\frac{1}{2}((a+\frac{v}{2})\cdot \frac{v}{p}+b\cdot \frac{p-v}{p})\)。

  • 若 \(i=r\),那么显然有转移 \(dp_{i,j}=dp_{i,j+1}+\frac{p}{4}\),这里 \(\frac{p}{4}\) 是 \(\frac{p}{2}\) 的期望时间乘以 \(\frac{1}{2}\) 的概率指向下方。

  • 若 \(j=c\),那么显然有转移 \(dp_{i,j}=dp_{i,j+1}+\frac{p}{4}\)。

时空复杂度均为 \(O(rc)\)。

代码

#include<bits/stdc++.h>
using namespace std;
using ld = long double;

const int MAXN = 1005;
const ld INF = 1e16;

int n, m, p;
ld dp[MAXN][MAXN];

int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  cin >> n >> m >> p;
  for(int i = n; i >= 1; --i) {
    for(int j = m; j >= 1; --j) {
      if(i != n || j != m) {
        if(i == n) {
          dp[i][j] = dp[i][j + 1] + 1.0l * p / 4.0l;
        }else if(j == m) {
          dp[i][j] = dp[i + 1][j] + 1.0l * p / 4.0l;
        }else {
          ld a = dp[i + 1][j], b = dp[i][j + 1];
          if(a > b) {
            swap(a, b);
          }
          ld x = min(0.0l + p, b - a);
          dp[i][j] = a / 2.0l + ((a + x / 2.0l) * x / p + 1.0l * b * (p - x) / p) / 2.0l;
        }
      }
    }
  }
  cout << fixed << setprecision(114) << dp[1][1];
  return 0;
}

D. NAC 子序列

题目描述

给定一个长度为 \(N\) 的仅由大写英文字母和 ? 构成的字符串 \(S\),你要将 \(S\) 中每个字符 ? 替换成任意大写英文字母。求有多少种替换方式使得 \(S\) 中恰好有 \(k\) 个子序列 NAC

思路

首先,如果 \((\frac{N}{3})^3<k\),那么直接输出无解。因为我们可以前中后分别放 \(\frac{N}{3}\) 个 NAC

令 \(dp_{i,a,b,c}\) 表示考虑前 \(i\) 个,有 \(a\) 个 N,\(b\) 个 NA,\(c\) 个 NAC 是否可行。由于只用记录是否可行,所以使用 bitset 优化转移即可。

时空复杂度均为 \(O(\frac{N^7}{w\cdot V})\)。其中 \(w=32\),\(V=2^2\cdot 3^3\)。

代码

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 41;

int n, m;
string s, ans;
bitset<MAXN * MAXN * MAXN / 27> dp[MAXN][MAXN][MAXN * MAXN / 4];

int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  cin >> n >> m >> s;
  s = ' ' + s;
  if((n / 3 + (n % 3 > 0)) * (n / 3 + (n % 3 > 1)) * (n / 3) < m) {
    cout << -1;
    return 0;
  }
  dp[0][0][0][0] = 1;
  for(int i = 1; i <= n; ++i) {
    for(int j = 0; j <= n; ++j) {
      for(int k = 0; k <= n * n / 4; ++k) {
        if((s[i] == 'N' || s[i] == '?') && j) {
          dp[i][j][k] |= dp[i - 1][j - 1][k];
        }
        if((s[i] == 'A' || s[i] == '?') && k >= j) {
          dp[i][j][k] |= dp[i - 1][j][k - j];
        }
        if(s[i] == 'C' || s[i] == '?') {
          dp[i][j][k] |= (dp[i - 1][j][k] << k);
        }
        if(s[i] != 'N' && s[i] != 'A' && s[i] != 'C') {
          dp[i][j][k] |= dp[i - 1][j][k];
        }
      }
    }
  }
  for(int i = 1; i <= n; ++i) {
    for(int j = 0; j <= n * n / 4; ++j) {
      if(dp[n][i][j][m]) {
        int k = m;
        for(int id = n; id >= 1; --id) {
          if((s[id] == 'N' || s[id] == '?') && i && dp[id - 1][i - 1][j][k]) {
            ans += 'N', i--;
          }else if((s[id] == 'A' || s[id] == '?') && j >= i && dp[id - 1][i][j - i][k]) {
            ans += 'A', j -= i;
          }else if((s[id] == 'C' || s[id] == '?') && k >= j && dp[id - 1][i][j][k - j]) {
            ans += 'C', k -= j;
          }else {
            ans += (s[id] == '?' ? 'B' : s[id]);
          }
        }
        reverse(ans.begin(), ans.end());
        cout << ans;
        return 0;
      }
    }
  }
  cout << -1;
  return 0;
}

标签:frac,21,int,2024,MAXN,初秋,ans,id,dp
From: https://www.cnblogs.com/yaosicheng124/p/18442726

相关文章

  • C/C++算法编程笔记(2024.9.26-9.30)
    一、并查集学习一:1、寻找根节点(两种)intfind(intx){if(x!=city[x]) city[x]=find(city[x]);returncity[x];}intfind(intx){ returnfa[x]==x?x:fa[x]=find(fa[x]);}2、合并不同集合voidmerge(intx,inty){inta=find(x);intb......
  • 上万套源码分享--01-92套-21-SpringBoot【90-98】
     springboot090中小企业设备管理系统设计与实现.rarspringboot092安康旅游网站的设计与实现.zipspringboot094基于web的酒店客房管理系统.zipspringboot095学生宿舍信息的系统.zipspringboot096基于springboot的租房管理系统,rarspringboot097大学生竞赛管理系统.rarspr......
  • 20240903
    mount我们会惊奇的发现,无论网格在哪里,只要有山覆盖了,那么这里的贡献一定是\(\sqrt{2}\),如下的图可以证明:那么我们就只用开一个线段树,维护的是最小值和最小值的出现次数,如果最小值不为\(0\),那么这部风就没有贡献,反之贡献就要加上最小值的出现次数细节由于我们可以......
  • 2024.10 训练日记
    我们将难度分为\(5\)个等级:\(\color{grey}\bigstar\)简单题,根本不配进入NOI的考场,做着玩玩。或者为模板题。\(\color{green}\bigstar\)签到题,在NOI赛场上强银选手几乎人人都会,如果赛场上不会的话对冲银的影响是非常大的,要避免。\(\color{blue}\bigstar\)中等题,在NOI......
  • 【办公类-48-03】20240930每月电子屏台账汇总成docx-3(三园区合并EXCLE,批量生成3份word
    背景需求:前期电子屏汇总是“总园”用“”问卷星”、“一分园”用“腾讯文档”,二分园“用“手写word””【办公类-48-02】20240407每月电子屏台账汇总成docx-2(腾讯文档xlsx导入docx,每页20条)【办公类-48-02】20240407每月电子屏台账汇总成docx-2(腾讯文档xlsx导入docx,每页20......
  • 2024年河北省职业院校技能大赛(高职组)软件测试赛项规程
    一、赛项名称赛项名称:软件测试赛项组别:高职组赛项归属产业:电子信息大类二、竞赛目标(一)引领职业院校专业建设与课程改革本赛项竞赛内容以《国家职业教育改革实施方案》为设计方针,以电子信息产业发展的人才需求为依据,以软件测试岗位真实工作过程为载体,全面检验高等职业院......
  • 【2024.9.30】NOIP2024 赛前集训-刷题训练(4)
    【2024.9.30】NOIP2024赛前集训-刷题训练(4)Problem-2000D-Codeforces给一串数和一串LR字符,L可以向右连接R,覆盖部分的LR不能再使用,但覆盖部分可以有被禁用的LR。每次覆盖部分的数字之和计入答案,求最大答案。手玩一下发现可以贪心。从最左边的L和最右边的R开始贪心。......
  • 20240930 模拟赛总结
    期望得分:100+80+0+20=200实际得分:0+80+10+20=110emmmm有点唐T1呃呃呃题读错了……怎么是至少啊啊啊啊啊啊啊啊啊啊啊。懒得喷。我的读题能力一直都很逆天!T280分是好构造的,最后20分很困难啊!我试了好多办法都失败了!浪费了1个小时,以后要衡量一下性价比,有这1小时,还不如去......
  • 高级java每日一道面试题-2024年9月30日-算法篇-LRU是什么?如何实现?
    如果有遗漏,评论区告诉我进行补充面试官:LRU是什么?如何实现?我回答:LRU(LeastRecentlyUsed)是一种常用的缓存淘汰策略,用于在缓存满时决定哪些数据应该被移除。LRU算法的基本思想是:当缓存达到其容量上限时,最近最少使用的数据会被优先淘汰。这种策略假设最近使用的数据在......
  • 高级java每日一道面试题-2024年9月30日-服务器篇[Redis篇]-Redis持久化有几种方式?
    如果有遗漏,评论区告诉我进行补充面试官:Redis持久化有几种方式?我回答:Redis是一个高性能的键值存储系统,常用于缓存、消息队列和实时数据分析等场景。为了保证数据的持久性,Redis提供了两种主要的持久化方式:RDB(RedisDatabaseBackup)和AOF(AppendOnlyFile)。这两种方......