Loading

2021.1~2做题记录

目录

  1. P2050
  2. P1169
  3. P1654
  4. P6858
  5. P3980
  6. AcWing206
  7. UVA11149
  8. P3254
  9. P4016
  10. AcWing226
  11. P6569
  12. P5490

正文

P2050 [NOI2012] 美食节 | 费用流

首先可以发现第 \(i\) 个厨师做他的第 \(j\) 个菜,时间可以表示为 \(j\times t\)。于是可以把厨师分成 \(mp\) 个点 \((i=1\dots m,j=1\dots p)\)。当 \((i,j)\) 被增广的时候,才加点 \((i,j+1)\),减少边数。用最大流控制所有菜都被做,然后用最小费用求出最小时间和。

P1169 [ZJOI2007]棋盘制作 | 动态规划、单调栈

第一问略。

对于第二问,先预处理出每个点向上、向左、向右最远能合法到达的长度,记作 \(uv_{i,j},lv_{i,j},rv_{i,j}\)。可以发现最终答案的竖向长度一定在 \(uv\) 中。于是枚举行 \(i\)\(j\),用单调栈求出每个 \(uv_{i,j}\) 向左最远到 \(k\) 才会满足 \(uv_{i,j}>uv_{i,k}\),向右亦然。然后就可以通过 \(lv_{i,j}\)\(k\) 求出向左的最大矩形了。

For(i,1,n){
		stk.top=0;
		For(j,1,m){
			while(stk.top&&uv[i][stk.s[stk.top]]>=uv[i][j]) --stk.top;
			chkmax(ans2,min((j-stk.s[stk.top]),lv[i][j])*uv[i][j]);
			stk.s[++stk.top]=j;
		}
		stk.top=0;
		Dec(j,m,1){
			while(stk.top&&uv[i][stk.s[stk.top]]>=uv[i][j]) --stk.top;
			chkmax(ans2,min((stk.top?stk.s[stk.top]:m+1)-j,rv[i][j])*uv[i][j]);
			stk.s[++stk.top]=j;
		}
	}

P1654 OSU! | 期望 dp

发现这个 \(x^3\) 的 combo 分数不太好做,于是先考虑 \(x\)\(x^2\) 怎么做。

\(a_i\) 为前 \(i\) 次操作,连续的操作贡献 \(x\) 的分数的、\(i\) 为结尾的 combo 的期望。则显然有 \(a_i=p_i(a_{i-1}+1)\)

\(b_i\) 为贡献 \(x^2\) 的期望,则有 \(p_i\) 的概率会比 \(b_{i-1}\) 多贡献 \(2a_{i-1}+1\) (根据完全平方公式可得)。则 \(b_i=p_i(b_{i-1}+2a_{i-1}+1)\)

仿照 \(a_i,b_i\),可以得出 \(f_i=(1-p_i)f_{i-1}+p_i(f_i-1+3b_{i-1}+3a_{i-1}+1)\),即有 \(p_i\) 的概率比 \(f_{i-1}\)\(3b_{i-1}+3a_{i-1}+1\),有 \((1-p_i)\) 的概率不变。这样 \(f_n\) 就是答案了。

P6858 深海少女与胖头鱼 | 期望 dp

首先考虑一个比较暴力的想法:设 \(f_{i,j}\) 为有 \(i\) 条带圣盾的,\(j\) 条不带圣盾的,期望需要打几次。

那么 \(f_{i,j}=\dfrac{if_{i+j-1,1}+jf_{i,j-1}}{i+j}+1\)。可以发现我们只需要用到 \(f_{i,1}\)\(f_{n,j}\)。如果我们能够在 \(O(1)\) 的时间内计算出 \(f_{i,1}\),那么问题就被解决了。

推式子得 \(f_{0,1}=1,f_{i,1}=f_{i-1,1}+i+2\)。通项公式显然为 \(f_{i,1}=1+2i+\frac{i(i+1)}{2}\)

于是我们就可以在 \(O(m \log 998244353)\) 的时间复杂度内完成此题。

P3980 [NOI2008] 志愿者招募 | 费用流

建模十分巧妙。

假设一开始有 \(\inf\) 名志愿者。那么我们需要把最大流限制为 \(\inf\),即所有志愿者都需要到终点。

对于第 \(i\) 天和第 \((i+1)\) 天中间连一条流为 \(\inf-a_i\),费用为 \(0\) 的边,代表这些志愿者可以不干活过去。

对于每个 \((s,t,c)\) 连边 \((s,t+1,\inf,c)\),代表这些志愿者需要付费让他们过去。

跑费用流。

AcWing 206. 石头游戏 | 矩阵加速

首先,因为操作序列长度不超过 \(6\),且最多有 \(10\) 种,所以每过 \(60\) 秒,所有位置的操作序列都会和 \(60\) 秒之前的一样。

于是可以算出 \(60\) 个转移矩阵 \(A_{1\dots 60}\),每个矩阵都是 \((nm+1)\times (nm+1)\) 的。对于每种操作分别处理一下即可。

这里有一个很巧妙的思路:用多出来的那一行记录常数项,这样加石子的时候会很方便。即,令 \(A_{1\dots60,nm+1,nm+1}=1\)

算出 \((\prod A_{1\dots60})^{t/60}\),再用矩阵乘法补齐剩下的 \(t\bmod 60\) 即可。

UVA11149 Power of Matrix | 矩阵乘法、分治

https://www.luogu.com.cn/blog/alan-zhao/solution-uva11149

P3254 圆桌问题 | 二分图多重匹配

略。

考试的时候写错了一个地方,丢人。

P4016 负载平衡问题 | 费用流

略。

AcWing226 233矩阵 | 矩阵加速

考虑把同一列的东西放在一个矩阵里面。构造转移矩阵的时候,可以把同一列的元素之间的加法转化为前缀和。

P6569 [NOI Online #3 提高组] 魔法值 | 矩阵加速、倍增

构造 \(0/1\) 矩阵,证明其乘法具有结合律。然后倍增预处理 \(A^{2^k}\),每次进行二进制拆分即可。

P5490 【模板】扫描线 | 线段树

这题的线段树可以通过神奇的 Pushup 操作来避免懒标记。具体可以见《算法竞赛进阶指南》中“线段树”一节。

posted @ 2021-01-23 20:20  Alan_Zhao_2007  阅读(75)  评论(0编辑  收藏  举报