1860D Balanced String
首先只能是0和1交换,1在
i
i
i位置,0在
j
j
j位置,每交换一次产生的贡献是
2
∗
(
i
−
j
)
2*(i-j)
2∗(i−j),所以我们可以先算出原01串中所需要的贡献
m
m
m,我们发现找到
t
o
l
tol
tol 个1和0的位置
i
k
,
j
k
i_k,j_k
ik,jk 且
∑
k
t
o
l
i
k
−
j
k
=
m
\sum_{k}^{tol} i_k-j_k=m
∑ktolik−jk=m,我们可以拆开
∑
k
t
o
l
i
k
−
∑
k
t
o
l
j
k
=
m
\sum_{k}^{tol} i_k- \sum_{k}^{tol} j_k=m
∑ktolik−∑ktoljk=m,然后分别dp出选tol个数,0,1的位置和分别有那些状态可以达到,易证位置和小于
n
2
n^2
n2,然后枚举
t
o
l
tol
tol,枚举1的位置和,算出0的位置和,判断两个状态是否能达到
时间复杂度
O
(
n
4
)
O(n^4)
O(n4)
void solve(){
std::string s;
std::cin>>s;
int n=s.length();
std::vector<int> a(n+1);
int sum=0,m=0;
for (int i=1;i<=n;i++){
a[i]=s[i-1]-'0';
if (a[i]){
m-=i-1-sum;
}else{
m+=sum;
}
sum+=a[i];
}
m>>=1;
std::vector<std::vector<int>> dp0(n+1,std::vector<int>(n*n+1)),dp1(n+1,std::vector<int>(n*n+1));
dp0[0][0]=dp1[0][0]=1;
for (int i=1;i<=n;i++){
for (int j=i;j>=1;j--){
for (int k=n*n;k>=i;k--){
if (a[i]){
dp1[j][k]|=dp1[j-1][k-i];
}else{
dp0[j][k]|=dp0[j-1][k-i];
}
}
}
}
m=-m;
for (int i=0;i<=n;i++){
for (int j=0;j<=n*n;j++){
int k=j-m;
if (k>=0&&k<=n*n&&dp1[i][j]&&dp0[i][k]){
std::cout<<i;
return;
}
}
}
}
1860E Fast Travel Text Editor
首先注意到是小写字母,说明最多 26 * 26 种组合方式,然后发现题意每次操作代价都为1,考虑建图,发现连边和对点的定义不好搞,考虑bfs,定义
d
i
s
i
,
j
,
x
dis_{i,j,x}
disi,j,x,表示当前点
x
x
x,到某个形如
′
a
′
+
i
,
′
a
′
+
j
'a'+i,'a'+j
′a′+i,′a′+j位置的最小距离,这样我们每次询问只要枚举 26 * 26 次,类似Floyed找中转点的方法,
m
i
n
(
y
−
x
,
d
i
s
i
,
j
,
x
+
d
i
s
i
,
j
,
y
+
1
)
min(y-x,dis_{i,j,x}+dis_{i,j,y}+1)
min(y−x,disi,j,x+disi,j,y+1)。文章来源:https://www.toymoban.com/news/detail-658559.html
我们枚举每个
i
,
j
i,j
i,j,然后从形如
′
a
′
+
i
,
′
a
′
+
j
'a'+i,'a'+j
′a′+i,′a′+j的位置出发,bfs向外扩展,更新各点的
d
i
s
i
,
j
,
x
dis_{i,j,x}
disi,j,x,每次扩展除了到
x
+
1
x+1
x+1和
x
−
1
x-1
x−1点外,还要让
x
x
x通过第三种操作跳跃到其它点,由于每个点最多入队一次,所以时间复杂度为
O
(
2
6
2
∣
s
∣
)
O(26^2\vert s \vert)
O(262∣s∣)
总时间复杂度
O
(
2
6
2
(
m
+
∣
s
∣
)
)
O(26^2 (m+\vert s \vert))
O(262(m+∣s∣))文章来源地址https://www.toymoban.com/news/detail-658559.html
const int inf=1e9;
void solve(){
std::string s;
std::cin>>s;
int n=s.length();
std::vector<int> pos[26][26];
for (int i=1;i<n;i++){
pos[s[i-1]-'a'][s[i]-'a'].push_back(i);
}
std::vector dis(26,std::vector(26,std::vector(n+2,inf)));
for (int i=0;i<26;i++){
for (int j=0;j<26;j++){
std::queue<int> q;
for (auto x:pos[i][j]){
q.push(x);
dis[i][j][x]=0;
}
std::vector<std::vector<int>> vis(26,std::vector<int>(26));
vis[i][j]=1;
while (!q.empty()){
int x=q.front();
q.pop();
if (x-1>=1&&dis[i][j][x-1]==inf){
dis[i][j][x-1]=dis[i][j][x]+1;
q.push(x-1);
}
if (x+1<n&&dis[i][j][x+1]==inf){
dis[i][j][x+1]=dis[i][j][x]+1;
q.push(x+1);
}
int l=s[x-1]-'a',r=s[x]-'a';
if (!vis[l][r]){
vis[l][r]=1;
for (auto v:pos[l][r]){
if (dis[i][j][v]==inf){
dis[i][j][v]=dis[i][j][x]+1;
q.push(v);
}
}
}
}
}
}
int m;
std::cin>>m;
while (m--){
int x,y;
std::cin>>x>>y;
int ans=abs(x-y);
for (int i=0;i<26;i++){
for (int j=0;j<26;j++){
ans=std::min(ans,dis[i][j][x]+dis[i][j][y]+1);
}
}
std::cout<<ans<<"\n";
}
}
到了这里,关于Educational Codeforces Round 153 D-E dp,bfs的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!