0%

思路讲解

简单来说,就是第一次炸了以后还能存活下来的金块,一定能活下来。

那么形式化的理解就是说第一次炸完以后,剩下的空间就足够其他炸弹进行一些精细操作了。

然后枚举+二维前缀和,就可以用二维前缀和来求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FOR(i,1,N){
FOR(j,1,M){
Sum[i][j]=Sum[i-1][j]+Sum[i][j-1]+(G[i][j]=='g')-Sum[i-1][j-1];
}
}
ll ans=0;
FOR(i,1,N){
FOR(j,1,M){
if(G[i][j]=='.'){
ll xl=max(i-K+1,1ll),xr=min(i+K-1,N),yl=max(1ll,j-K+1),yr=min(M,j+K-1);
ll lans=Sum[xr][yr]+Sum[xl-1][yl-1]-Sum[xl-1][yr]-Sum[xr][yl-1];
ans=max(ans,Sum[N][M]-lans);
}
}
}

AC代码

https://codeforces.com/contest/2113/submission/325681423

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

思路讲解

我感觉可以搞dp(结果看了第二个样例觉得不太行)。

那么其实就是局部最优可以推得全局最优,非常经典的贪心。

那么为什么说这个B朝右朝左选一个最大的就最优了?不会相互影响吗?

image

那我们来看一个你认为会相互影响的,可以看到,这个是矛盾的。所以不会相互影响

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
FOR(i,1,N){
++cnt[S[i]-'A'];
if(S[i]=='B'){
L[i]=cnt[0];
}else if(S[i]=='C'){
cnt[0]=0;
}else{

}
}
cnt.assign(10,0);
ROF(i,N,1){
++cnt[S[i]-'A'];
if(S[i]=='B'){
R[i]=cnt[2];
}else if(S[i]=='A'){
cnt[2]=0;
}else{

}
}
FOR(i,1,N){
if(S[i]=='B'){
ans+=max(L[i],R[i]);
}
}

AC代码

https://www.codechef.com/viewsolution/1167971455

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

写了一个下午,一直WA,思路错了。

思路讲解

主要的收获就是打表

ll Ans[MAXN]={0,2,1,3,5,4};

最重要的就是想出来这个,让3,5靠在一起,这样就直接搞定了,后面的构造是很容易的。

AC代码

https://www.codechef.com/viewsolution/1167807254

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

思路讲解

通过倒序遍历,就可以提前知道这个操作是否会影响最终的服务器端字符串。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ROF(i,Q,1){
if(op[i]==1){
if(idx==pos[i]){
// 那么为什么将服务器字符串赋值给电脑端的操作需要重置字符串为0?
// 其实答案就藏在上面这个if条件中
idx=0;
}
}else if(op[i]==2){
if(idx==pos[i]){ // 那么当我们发现改变该字符串会改变最终状态
ans+=S[i];
}
}else{
// 比较好理解,就是说当发现sever发现其是来自于pos[i]的时候将idx设置为pos[i]
if(idx==0){
// 这个条件就是说如果pos[i]其会改变最终状态,前面这个pos[i]必须是白板
idx=pos[i];
}
}
}

AC代码

https://atcoder.jp/contests/abc411/submissions/66994292

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