vi设计理念和设计思路,太原百度网站排名优化,质控中心网站建设申请,微信公众号运营模式解析
比较复杂的一道题 看数据范围#xff0c;我们肯定要从种类很少的颜色入手
因为第二种加边方式和颜色密切相关 所以设计disi,kdis_{i,k}disi,k表示 i 号节点到颜色为 k 的节点的最小步数 通过对每个k bfs一遍就能得出答案 然后两个点之间的距离就可以写出转移式#…解析
比较复杂的一道题 看数据范围我们肯定要从种类很少的颜色入手
因为第二种加边方式和颜色密切相关 所以设计disi,kdis_{i,k}disi,k表示 i 号节点到颜色为 k 的节点的最小步数 通过对每个k bfs一遍就能得出答案 然后两个点之间的距离就可以写出转移式 fi,jmin(∣i−j∣,mink8disi,kdisj,k1)f_{i,j}\min (|i-j|, \min_k^8dis_{i,k}dis_{j,k}1)fi,jmin(∣i−j∣,kmin8disi,kdisj,k1) 考虑这样我们就得到了一种n2n^2n2的算法
考虑如何加速 首先由于最差情况就是aabbcc…这样的情形答案不会超过15所以第一项我们只需要在距离[i-15,i-1]的区间考虑可以暴力求解
关键是对后面一项的处理
设计coli,jcol_{i,j}coli,j表示从任意 i 颜色的块走到任意 j 颜色的块的最小步数 这个也可以在bfs时顺便转移 可以得到一个不等关系式 colai,j≤disi,j≤colai,j1col_{a_i,j}\leq dis_{i,j}\leq col_{a_i,j}1colai,j≤disi,j≤colai,j1 为什么 也比较显然如果任何一个不等关系不符合col和dis数组就会在bfs时互相更新使这个不等关系重新满足
所以我们的dis-col的差值只可能为0或1,我们可以把8个对应的差值状态压缩然后一起求解
实现上建议把所有状态的结果预处理出来会在瓶颈部分少一个8的循环应该快很多
代码
#includebits/stdc.hconst int N1e5100;
const int mod1e97;
#define ll long long
using namespace std;
inline ll read() {ll x(0),f(1);char cgetchar();while(!isdigit(c)) {if(c-)f-1;cgetchar();}while(isdigit(c)) {x(x1)(x3)c-0;cgetchar();}return x*f;
}int n,m;int col[9][9],dis[N][9],a[N];
bool vis[N];
char s[N];
int q[N],st,ed;
int dx[3]{0,1,-1};
vectorintv[9];
void bfs(int k){memset(vis,0,sizeof(vis));st1;ed0;for(int i1;in;i){if(a[i]k) q[ed]i,vis[i]1;}col[k][k]0;while(sted){int nowq[st];for(int i1;i2;i){int tonowdx[i];if(vis[to]||to0||ton) continue;vis[to]1;dis[to][k]dis[now][k]1;q[ed]to;}if(col[k][a[now]]1e9){col[k][a[now]]dis[now][k];for(int i0,tpv[a[now]].size();itp;i){int xv[a[now]][i];if(!vis[x]){dis[x][k]dis[now][k]1;q[ed]x;vis[x]1;}}}}return;
}
int mi[15],cst[2060][2060];
int sta[N],num[2060];
int main(){
#ifndef ONLINE_JUDGEfreopen(a.in,r,stdin);freopen(a.out,w,stdout);
#endifnread();scanf( %s,s1);for(int i1;i8;i){for(int j1;j8;j) col[i][j]1e9;}for(int i1;in;i) a[i]s[i]-a1,v[a[i]].push_back(i);for(int i1;i8;i) bfs(i);mi[0]1;for(int i1;i11;i) mi[i]mi[i-1]1;for(int i0;imi[11];i){for(int j0;jmi[11];j){int a(i8)1,b(j8)1;int res2e9;for(int k1;k8;k){resmin(res,col[a][k]1col[b][k]((imi[k-1])?1:0)((jmi[k-1])?1:0));}cst[i][j]res;}}for(int i1;in;i){int sa[i]-1,oa[i];for(int k8;k1;k--){s1;if(dis[i][k]col[o][k]) s|1;}sta[i]s;}int ans(0);ll sum(0);for(int i1;in;i){for(int jmax(i-15,1);ji;j){int wmin(i-j,cst[sta[i]][sta[j]]);if(wans){answ;sum1;}else if(wans) sum;}for(int s0;smi[11];s){if(!num[s]) continue;if(cst[s][sta[i]]ans) anscst[s][sta[i]],sumnum[s];else if(cst[s][sta[i]]ans) sumnum[s];}if(i16) num[sta[i-15]];}//printf(st[1]%d st[7]%d\n,sta[1],sta[7]);//printf(dis[1][1]%d col[3][1]%d\n,dis[1][1],col[3][1]);printf(%d %lld\n,ans,sum);return 0;
}