0%

思路讲解

和这道题目比较像,但又不完全一样。

CF-1011-D. Serval and Kaitenzushi Buffet

套路那比较像,但不完全一样。

其实最重要的就是要找到一个贪心结构,我们这边发现,倒过来遍历,然后一直选左括号,一旦右括号不够了,这个时候就要选一个左括号变为右括号。又因为前面的左括号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
	ROF(i,N-1,1){
ans+=A[i];
pq.push(i);
balance--;
if(balance<0){ // 倒过来遍历,结果发现右括号数量不够了,这个时候必须牺牲一个左括号了
ans-=A[pq.top()];
// #ifdef LOCAL
// debug(pq.top());
// debug(A[pq.top()]);
// #endif
pq.pop();
balance+=2;
}
}

AC代码

https://atcoder.jp/contests/abc407/submissions/66140638

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

思路讲解

其实还是比较简单的,就是如果说最后的答案不涉及这个顺序问题,其实是可以不用管这个顺序的。

当然,所有选择的可能都是要管的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 选择1:不放多米诺骨牌,跳过当前格子
vis[i][j] = true;
dfs(covered_xor);
vis[i][j] = false;

// 选择2:尝试垂直放置多米诺骨牌 (向下)
if (i + 1 <= N && !vis[i + 1][j]) {
vis[i][j] = vis[i + 1][j] = true;
dfs(covered_xor ^ A[i][j] ^ A[i + 1][j]);
vis[i][j] = vis[i + 1][j] = false;
}

// 选择3:尝试水平放置多米诺骨牌 (向右)
if (j + 1 <= M && !vis[i][j + 1]) {
vis[i][j] = vis[i][j + 1] = true;
dfs(covered_xor ^ A[i][j] ^ A[i][j + 1]);
vis[i][j] = vis[i][j + 1] = false;
}

AC代码

https://atcoder.jp/contests/abc407/submissions/66113167

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

思路讲解

image

首先,拿到题目,发现为01串,这个时候就要想到分块思想。

image

如何选用乘法压缩石块那?更优解。让B作为首位。但这种情况必须后面有A(即 idx≥3)。

image

最后代码实现就是这样

1
2
3
4
5
6
7
if(idx==1){
cout<<1<<"\n";
}else if(idx==2){
cout<<1+min(SZ(g[st[2]-'A']),3)<<"\n";
}else{
cout<<2<<"\n";
}

AC代码

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

思路讲解

从这道题目过来的。

ABC-402-E - Payment Required(酷似背包的状压dp)

其实还是有挺多不大一样的地方。

参考这篇题解。

https://www.luogu.com.cn/article/8f5nvjkq

这个主要难度还是在怎么样理解这个倒序遍历上面。

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
for(int k=K;k>=1;--k){	// 倒过来枚举,因为正过来不一定有合法转移
for(int s=0;s<(1<<N);++s){ // s为获得的宝物清单
for(int idx=1;idx<=N;++idx){ // idx为这一轮获得的宝物编号
ll idx_=idx-1;
bool canTran=true;
FOR(i,0,SZ(g[idx])-1){
if((s|(1<<(g[idx][i]-1)) ) == s){ // | 以后没起作用说明s里包括了
canTran=true;
}else{ // 如果前提条件中有东西是不存在在
canTran=false;
break;
}
}
if(canTran){
dp[k][s]+=max(dp[k+1][s|(1<<idx_)]+scr[idx],
dp[k+1][s]);
}else{
// 相当于白获得了。
dp[k][s]+=dp[k+1][s];
}
}
dp[k][s]/=N;
}
}
cout<<setprecision(6)<<fixed<<dp[K][0]<<"\n";

不过我们也可以作死,试一试正序遍历,其实也没有什么太大问题。

https://www.luogu.com.cn/record/218153981

那么如何理解dp[K][0]是

AC代码

https://www.luogu.com.cn/record/218152633

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

思路讲解

赛时过的,记录一下。

image

首先,注意到,(u+v)modN(u+v)\mod N 值相等的线平行。全部组合中,减去平行的组合,就是答案。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
	FOR(i,1,M){
ll u,v;
cin>>u>>v;
// G.pb(u,v);
Sum.pb((u+v)%N);
}
ll ans=M*(M-1),lans=0;
sort(all(Sum));
FOR(i,0,SZ(Sum)-1){
ll num=upper_bound(all(Sum),Sum[i])-lower_bound(all(Sum),Sum[i])-1;
ans-=num;
// #ifdef LOCAL
// debug(Sum[i]);
// debug(num);
// #endif
}

AC代码

https://atcoder.jp/contests/abc402/submissions/66034983

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