20260918 每日 1.0 3.0 4.0



No.3279 Dhole vs Monster

https://yukicoder.me/problems/no/3279

Note

模拟

namespace XK {
  void solve() {
  	int f[] = {0, 390,429,468,507,546};
  	int x; string t; cin >> x >> t;
  	if(t == "Beat") cout << f[x + 1];
  	else cout << f[x];
  }
};

No.2899 Taffy Permutation

https://yukicoder.me/problems/no/2899

Note

给定一个由 0 和 1 构成的长度为 $N$ 的字符串 $S$,求满足下面条件的长度为 $N$ 的排列数量。

  • 对于所有满足 $(i \lt j)$ 且 $S_i = 0, S_j = 1$ 的所有二元组 $(i,j)$,有 $p_i \lt p_j$

这是3.0?

首先我们会发现,0 与 0 之间,1 与 1 之间没有约束,于是我们会想到定义:

$f_{i,k} :=$ 考虑到第 $i$ 位的时候,当前 $max(P_{S_i=0}) = k$ 的数量

我们会发现无法约束 1 的选法,也不能统计还需要多少,而再加一维度则不能通过,考虑转化。

我们会想到,$k$ 的大小并不影响选法,影响选法的是,$\lt k$ 的部分剩下的可选点,于是定义:

$f_{i,j} :=$ 考虑到第 $i$ 位的时候,当前比 $max(P_{S_i=0})$ 小的还没有用的数字数量刚好是 $j$ 的方案数

下面考虑状态转移:

接下来考虑初始值:

答案就是 $f_{N-1,0}$,这是显然的,因为你要全部填完。

复杂度是 $O(N^2)$ 的,空间复杂度可以通过滚动数组优化到 $O(N)$,但本题目不要求优化。

namespace XK {
const ll mod = 998244353;
struct mm {
};
  void solve() {
  	int N; cin >> N; string S; cin >> S;
  	V<V<mm>> f(N, V<mm>(N + 1, 0));
  	if(S[0] == '1') f[0][0] = N;
  	else rep(i, N + 1) f[0][i] = 1;
  	Rep(i, 1, N) {
  		if(S[i] == '1') {
  			rep(j, N + 1) if(i + j < N) f[i][j] += f[i - 1][j] * (N - i - j);
  		} else {
  			auto nf = f[i - 1];
  			Rep(j, 1, N + 1) nf[j] += nf[j - 1];
  			rep(j, N + 1) f[i][j] += nf[j];
  			Rep(j, 1, N + 1) f[i][j - 1] += f[i - 1][j] * j;
  		}
  	}
  	cout << f[N - 1][0].x;
  }
};

今天的4.0是早期4.0,打暴力就能通过,不在这里放了