「HAOI2016」放棋子】的更多相关文章

题解 水题,可惜要写高精度有点烦 一看障碍物的摆放方式和最后的答案没有关系,于是干脆不读了,直接二项式反演可以得到 设\(g_k\)为一种摆放方式恰好占了k个障碍物 \(f_k = \sum_{i = k}^{n} \binom{i}{k} g_{i}\) 可以得到 \(g_0 = \sum_{k = 0}^{n} (-1)^{k} \binom{k}{0} f_{i}\) \(g_0 = \sum_{k = 0}^{n} (-1)^{k} \binom{n}{k} (n - k)!\) 拆开可…
题目链接 戳这 前置知识 错位排序 Solution 我们可以观察发现,每一行的障碍位置对答案并没有影响. 于是我们可以将此时的矩阵化成如下形式: \[ 1\ \ 0\ \ 0\ \ 0\\ 0\ \ 1\ \ 0\ \ 0\\ 0\ \ 0\ \ 1\ \ 0\\ 0\ \ 0\ \ 0\ \ 1 \] 此时障碍列的排列为: 1 2 3 4 于是我们问题可以转化为: 从每行中选出一个\(1~n\)的没出现的书且和障碍不相同 即:问一个\(1~n\)的数列的排列与原数列的位置都不相同的个数 所以…
答案就是错排数 n = int(input()) f = [0] * 205 f[0] = 1 for i in range(2, n+1): f[i] = (i-1) * (f[i-1] + f[i-2]) print(f[n])…
「HAOI2016」字符合并 题意: ​ 有一个长度为\(n\)的\(01\)串,你可以每次将相邻的\(k\)个字符合并,得到一个新的字符并获得一定分数.得到的新字符和分数由这\(k\)个字符确定.你需要求出你能获得的最大分数.(\(n\le 300,k\leq8\)) 题解: ​ 关键是要想到区间dp.记\(f[i][j][s]\),表示区间\([i,j]\),合并后状态为\(s\)的最大值.注意到长度模\(k\)余\(1\)的区间都可合并成一个字符,那么转移枚举的中点每次可以跳动\(k-1\…
题面 题解 任意两个障碍不在同一列 要求你放$N$个棋子也满足每行只有一枚棋子,每列只有一枚棋子的限制. 这™不就是个错排吗??? $$ h_i=(n-1)(h_{i-1}+h_{i-2}),h_1=0,h_2=1 $$ 写个高精度就好了... 代码 #include<cstdio> #include<cstring> #include<cctype> #include<algorithm> #define RG register inline int re…
题解 做后缀自动机题要一点脑洞,脑洞一开,就过了 我们显然要拿第二个串跑第一个串的后缀自动机 我们可以求出第二个串每个位置匹配到的节点,和匹配的长度L 那么我们统计一个后缀树上的根缀和,表示这样个节点的路径字符串的所有后缀在串中出现过多少次(路径字符串就是根到这个点的路径中等于这个节点len值的串) 统计方法是p->sum = p->par->sum + p->cnt * (p->len - p->par->len) 然后我们匹配到的位置不一定完整匹配了路径字符串…
题解 dp[i][j][S]表示区间[i,j]内剩余的数位状压后为S的最大值 这样转移起来不就是\(n^3 2^8\)了吗 冷静一下,我们可以发现一段区间内剩下的数位的个数是一定的,也就是我们可以在枚举位数上减少一定复杂度 我们转移的时候枚举一个末尾,也就是 \(dp[i][j][S] = dp[i][k][S >> 1] + dp[k + 1][j][S & 1]\) 我们还需要保证[k + 1,j]的长度-1后是(K - 1)的倍数 这样的话最后跑得还是很快的 代码 #includ…
题解 我对莫队真是一无所知 这个东西显然可以用圆方树转成一个dfs序列 然后呢,用莫队计算每个询问区间的每个数出现的次数,从而顺带计算每个数字的奇偶性 但是我们要查的数字也用一个范围,可以直接用分块维护,修改\(O(1)\)查询\(O(n)\) 代码 #include <bits/stdc++.h> #define enter putchar('\n') #define space putchar(' ') #define pii pair<int,int> #define fi…
ref #include <iostream> #include <cstring> #include <cstdio> using namespace std; typedef long long ll; int n, k, a[305], c[305]; ll w[305], dp[305][305][265], g[2]; int main(){ memset(dp, 0xcf, sizeof(dp)); cin>>n>>k; for(in…
题目链接 解题思路 简单的DAG上DP即可. 参考程序 #include <bits/stdc++.h> using namespace std; const int Maxn = 100010; const int Maxm = 200010; struct edge { int To, Next; }; edge Edge[ Maxm ]; int Start[ Maxn ], Used; int n, m, In[ Maxn ], Out[ Maxn ], Dp[ Maxn ], L,…