0%

思路讲解

就是要注意到,如果一段连续的相同的数字是不会影响结果的,因此需要把他们缩减。

AC代码

心路历程(WA,TLE,MLE……)

https://codeforces.com/contest/2108/submission/317973413

1
2
3
4
1
3
11 10 10

思路讲解

首先贪心的,我们在每个位置上总归想跳的最远,且在每个位置上都跳的最远,得到的一定是最少跳跃次数的。

那么这个每个位置上通过加一个字母能够一次跳到的最远位置怎么得到的那?其实就是所有合法字母中上一次出现的位置最远的字母的位置(如果有一个合法字母前面没出现过,那我们就认为他直接跳出去结束了)。

1
2
3
4
5
6
7
8
9
10
11
12
ROF(i,N-1,0){
FOR(j,0,K-1){
if(Pos[j].empty()){
JumpFar[i]=N;
JumpCh[i][j]=N;
}else{
JumpFar[i]=max(Pos[j].back(),JumpFar[i]);
JumpCh[i][j]=Pos[j].back();
}
}
Pos[S[i]-'a'].pb(i);
}

然后知道了在这个位置上最远能跳多远,那么我们知道最多要跳多少次那?可以通过记忆化搜索。

1
2
3
4
5
6
7
8
9
ll dfs(ll x){
if(x>=N) return 0;
if(dp[x]!=0) return dp[x];
return dfs(JumpFar[x])+1;
}

ROF(i,N-1,0){
dp[i]=dfs(i);
}

最后这个串需要用多少位原串需要跳跃处理,否则会 TLETLE,最坏 O(NQ)O(NQ) 时间复杂度。

AC代码

https://codeforces.com/contest/2104/submission/317799371

心路历程(WA,TLE,MLE……)

https://codeforces.com/contest/2104/submission/317796467

对比对部分没有优化。

思路讲解

其实思路还是很简单的,就是符合要求的一列数字,数字总和最小的就是 2357112,3,5,7,11,…

这样的一串素数数列。

证明?那么我们假设其中一个数字可以减去1,首先2不能-1(出现了1),那么其他的数字-1也不能(被2除)。

得证。

AC代码

https://codeforces.com/contest/2104/submission/317754416

心路历程(WA,TLE,MLE……)

思路讲解

无向图边的重定向问题。

只告诉你奇数的块的位置,不告诉你偶数的块的位置,问有多少条路径(取模mod)

image

其实比较难的就是想样例4,多个块共用一个块,这个时候怎么办?

image

把他转化为图论问题,其实就是问这张图上有多少条 151→5 路径?

这个有几种路径怎么算那?这其实根本用不到什么最小割,最大流什么的,割是用来解决不相交路径数量问题的。直接上dfs就行。

唉,这个直接暴力会TLE,毕竟数量太多了,一个一个统计一定会TLE的。

https://www.luogu.com.cn/problem/solution/CF2097B

其实想到见图了可以更进一步,直接将约束和点抽象为图。

image

主要就是把这个问题转化为了无向图方向确定问题。

AC代码

https://codeforces.com/contest/2097/submission/318339701

心路历程(WA,TLE,MLE……)

TLE

毕竟我的算法是去试每一条路径

https://codeforces.com/contest/2098/submission/317475573

调试中一个样例出的一些问题

通过暴力程序dfs我们得知,这个点直到(2,3)点,仍然有11条路径
但到了(1,4)点,我们就只有2条路径了。
因为有一个始源路径就是(2,5)->(3,3)->(3,4),(2,3)->(1,4)也需要
所以说问题出在passNum的统计上,(3,3)作为始祖路径之一,早已不是只有一条路径通过了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
inline void merge(ll x,ll y){
ll fax=find(x),fay=find(y);
if(x==y) {
// 增加了一个自环,也算是加了
rEdge[fax]+=1;
selfLoop[fax]=true;
#ifdef LOCAL
cerr << "--------selfLoop-----" << '\n';
#endif
return;
}else if(fax==fay){ // 这段斜体加粗要加上用来特判即不是自环,但在同一联通块的情况
rEdge[fay]+=1;
return;
}
rNode[fay]+=rNode[fax];
rEdge[fay]+=rEdge[fax]+1;
selfLoop[fay]|=selfLoop[fax];
fa[fax]=fay;
}

思路讲解

终于是看懂题目是什么意思了。其实就是问你这张生成网格中的0的联通块最多包含多少个0。

image

比如这张图中是包含9个。

那么唯一的问题就是,这张生成网格太大了,最多可能有4e10个块。这就有点恐怖了。

如果说跑dfs,bfs,O(n2)O(n^2) 无法通过此题。

唉,其实像这种题反而难想,因为暴力太容易想到,但是暴力的优化就不是很容易了,可能要另起炉灶了。

那么就直接使用dp的类似思路,一列一列的推过去,然后就做出来了?一次AC!

AC代码

心路历程(WA,TLE,MLE……)