0%

思路讲解

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……)

思路讲解

我勒个豆,比赛的时候没注意到,这个 N8N\le8。那么其实就很清楚了,状压dp。

首先呢,这个是不能用背包的,这是一个多重背包,乃至于多重都不一定是,因为如果这道题目他做出来了,他就可以不提交了。

状态转移是这样的,如果第 i 个物品在已经做出的题目清单(即状态s)中,那么他可以从已经做出来的状态转移,也可以从没有做出来的状态转移。

dp[x][s]=max((dp[xcost][s(1<<(idx1))]+score)poss+dp[xcost][s](1poss),dp[x][s])dp[x][s]=max({(dp[x-cost][s-(1<<(idx-1))]+score)*poss+dp[x-cost][s]*(1-poss),dp[x][s]})

那么如果不在已经做出的题目清单(即状态s)中,那么只能从没做出来的状态转移过来,即

dp[x][s]=max(dp[x][s],dp[xcost][s](1poss));dp[x][s]=max(dp[x][s],dp[x-cost][s]*(1-poss));

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
DB ans=0;
for(int x=1;x<=X;++x){
// 通过的题目集合
for(int s=1;s<=(1<<N);++s){
ll ops=s;
for(int idx=1;idx<=N;++idx){
ll score=Prob[idx][0],cost=Prob[idx][1];DB poss=Prob[idx][2]/100.0;
if(x<cost) {continue;}
if((1<<(idx-1))>s) break;
if((1<<(idx-1)|s)==s ){
dp[x][s]=max({(dp[x-cost][s-(1<<(idx-1))]+score)*poss+dp[x-cost][s]*(1-poss),dp[x][s]});
}else{
// 从没做出来转移过来
dp[x][s]=max(dp[x][s],dp[x-cost][s]*(1-poss));
}
}
ans=max(ans,dp[x][s]);
}
}

AC代码

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

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