3.7考试总结
作者:互联网
3.7考场总结
今日问题:
- 考场犯困
- 忘记删调试!!!
- 考试着急,没有审清题就考试作答
- 没有对知识进行迁移,怎么说呢,就是东西想的离正解都不远,但是就是差一点点才能感觉到正解的水平,说明最近学到的东西越来越多了,需要开始疏理,总结了,T2当时绝对是正解的思路,但是没有进一步的想,说明DP的思维和思路还是不很明确
T1
给出两个 \(n×m\) 的 \(01\) 矩阵 \(A,B\)。一次操作可以指定 \(A\) 中一个为 \(0\) 的位置,将它变为 \(1\),同时将该行该列其它元素变为 \(0\) 。求是否可能通过这些操作将 \(A\) 变成 \(B\)。
首先我们考虑,对于原问题来说限制很多,因为你让 \(A\) 的某个 \(0\) 变成 \(1\) 以后,对于所有的行列值都会有影响
那我们不妨倒过来考虑如何从 \(B\) 变成 \(A\)
我们发现这时候限制会小得多,因为等于你可以把一个 \(1\) 直接变成 \(0\),然后同行同列的随便填。
然后我们分开讨论,如果 \(B\) 的某一行有两个及以上的 1 应该 \(lock\) 掉,其余的统计一下是否都是 \(1\) 或者 \(0\) 即可
N 个鱼缸排成一列,按照 \(1,2,…,N\) 的顺序编号。第 \(i\) 个鱼缸里水的高度为 \(Hi\) ,保证 \(Hi<W\) 。
现在放入 \(M\) 条鱼,第 \(i\) 条鱼被放入第 \(P_i\) 个鱼缸,同时它最多能跳 \(J_i\) 单位。鱼 \(i\) 能从鱼缸 \(a\) 跳到鱼缸 \(b\) 当且仅当 \(|a−b|\le1\) 且 \(J_i>W−Ha\)。
现在每条鱼开始寻找朋友,他们从一开始所在的鱼缸开始跳,直到跳到某个鱼缸然后停下。等所有鱼都停下了,处在同一鱼缸的鱼就会相互认识。求最后相互认识的鱼的对数的最大值。
好题!
首先我们发现一条鱼肯定是在一个区间里面跳
第二个是一条鱼进入一个鱼比较多的鱼缸里必然更优
而且我们考虑,如果有若干个区间都在某一个点有交叉,那么其余的区间必然全部在这个点的左边或右边
这样的话这个题我们就做完了,中间实现有一些小细节,可以直接看代码
int n, m, w, k;
int h[N];
int l[M], r[M], tmp[M];
int f[M][M];
int val[M], sum[M];
signed main() {
read(n, m, w);
rep (i, 1, n) read(k), h[i] = w - k;
rep (i, 1, m) {
int p, j;
read(p, j);
l[i] = r[i] = p;
while (l[i] > 1 && j > h[l[i]]) l[i]--;
while (r[i] < n && j > h[r[i]]) r[i]++;
tmp[2 * i - 1] = l[i];
tmp[2 * i] = r[i];
}
sort(tmp + 1, tmp + 2 * m + 1);
int tot = unique(tmp + 1, tmp + 2 * m + 1) - tmp - 1;
rep (i, 1, m)
l[i] = lower_bound(tmp + 1, tmp + tot + 1, l[i]) - tmp,
r[i] = lower_bound(tmp + 1, tmp + tot + 1, r[i]) - tmp;
rep (len, 1, tot) {
rep (i, 1, tot - len + 1) {
int j = i + len - 1;
rep (k, 1, m)
if (i <= l[k] && r[k] <= j) sum[l[k]]++, sum[r[k] + 1]--;
rep (k, i, j)
sum[k] += sum[k - 1], f[i][j] = max(f[i][j], sum[k] * (sum[k] - 1) / 2 + f[i][k - 1] + f[k + 1][j]);
rep (k, i, j + 1) sum[k] = 0;
}
}
write(f[1][tot], '\n');
return 0;
}
// write:RevolutionBP
在欧洲很多皇室中,女性是绝对的领导者,给皇室家族的女士起名字是非常重要的一件事情。Joi 是一位研究欧洲皇室的历史学家,现在分给她一份工作,分析皇室家族中女士名字起名规则。为了方便分析,现在假定一共有 \(n\) 位皇族女士,编号从 \(1\) 号到 \(n\) 号。每一位皇族女士的名字都按照一个大写字母与她母亲的名字连在一起起名字,例外的是 \(1\) 号皇族女士,她是皇族的创始人,名字只有一个大写字母。
例如: ENERYS 是 AENERYS 的母亲(因为 AENERYS 这个名字是由一个大写字母 'A' 和 'ENERYS' 连在一起组成的,ENERYS 是她母亲的名字)。同样,AENERYS是 DAENERYS 和 YAENERYS 的母亲;现在 Joi 知道所有皇族女士的名字,现在需要你编写一个程序帮助 Joi 确定某些给定的字符串 \(s\) 作为前缀的皇族女士的人数。
题意:每个节点 \(i\) 都有一个母亲,节点 \(i\) 代表的字符串为字符 \(c\) + 她母亲的字符,给定几个字符串,试求以 \(s\) 为前缀的女士的人数
首先,好消息,直接在 \(trie\) 树上找可以获得86分的好成绩捏
正解也很明显,要写AC自动机,建好文本串以后直接查即可
int n, m, T, ans, x, tot;
int a[N], id[N], f[N], End[N];
char s[N];
struct ZPK {
int num, fail;
int son[26];
}tr[N];
inline void insert(int x, char y, int i) {
id[i] = tr[id[x]].son[y - 'A'] = ++ tot;
++ f[id[i]];
}
inline void Insert(char s[], int pos) {
int len = strlen(s), u = 0;
per (i, len - 1, 0) {
int v = s[i] - 'A';
if (!tr[u].son[v]) tr[u].son[v] = ++ tot;
u = tr[u].son[v];
}
End[pos] = u;
}
inline void build() {
queue <int> q;
rep (i, 0, 25) if (tr[0].son[i]) q.push(tr[0].son[i]);
while (!q.empty()) {
int u = q.front(); q.pop();
rep (i, 0, 25) {
if (tr[u].son[i]) tr[tr[u].son[i]].fail = tr[tr[u].fail].son[i], q.push(tr[u].son[i]);
else tr[u].son[i] = tr[tr[u].fail].son[i];
}
}
}
struct edge {
int to, nxt;
}e[N << 1];
int head[N], cnt;
inline void add(int u, int v) {
e[++cnt] = (edge){v, head[u]};
head[u] = cnt;
}
inline void dfs(int u) {
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
dfs(v), f[u] += f[v];
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("1.in", "r", stdin);
freopen("1.out", "w", stdout);
#endif
read(n, m);
rep (i, 1, n) {
char y; cin >> y;
read(x), insert(x, y, i);
}
rep (i, 1, m) scanf("%s", s), Insert(s, i);
build();
rep (i, 1, tot) add(tr[i].fail, i);
dfs(0);
rep (i, 1, m) write(f[End[i]], '\n');
return 0;
}
//write:RevolutionBP
标签:总结,tmp,int,rep,tr,tot,son,3.7,考试 来源: https://www.cnblogs.com/RevolutionBP/p/15979365.html