思路学习的这一篇
step1
首先我们设 \(mn_{i,j}\)为砝码 \(i\) -砝码 \(j\) 的最小值(下文以\(a_i\)和\(a_j\)代替)。
\(mx_{i,j}\)为\(a_i-a_j\)的最大值。
当设\(a_i\)和\(a_j\)的关系为\(g_{i,j}\)。
当\(g_{i,j}\)为=\(+\)时,
a[i] a[j] a[i]-a[j]3 1 22 1 13 2 1
明显,\(mx_{i,j}=2\),\(mn_{i,j}=1\)
当\(g_{i,j}\)为\(-\)时,
a[i] a[j] a[i]-a[j]1 3 -21 2 -12 3 -1
\(mx_{i,j}=-1\),\(mn_{i,j}=-2\)
当\(g_{i,j}\)为\(=\)时
\(\because a_i=a_j\)
\(\therefore mn_{i,j}=mn_{i,j}=0\)
最后当\(g_{i,j}\)为\(?\)时
\(mx_{i,j}=2\),\(mn_{i,j}=-2\)(相当于\(+\)和\(-\))的结合
综上
\[\begin{cases}
mx_{i,j}=2,mn_{i,j}=1 & g_{i,j}为+\\
mx_{i,j}=-1,mn_{i,j}=-2 & g_{i,j}为-\\
mx_{i,j}=0,mn_{i,j}=0 & g_{i,j}为=\\
mx_{i,j}=2,mn_{i,j}=-2 & g_{i,j}为?\\
\end{cases}
\]
step2
我们知道了\(mx\)和\(mn\)的值,接下来题面说要唯一情况,所以我们要差分约束
\(mn_{i,j}\)记录的是\(a_i-a_j的最小差值\)。那我们可以找一个\(k\)。
\[mn_{i,j}=a_i-a_j\\
\hspace{7em} =a_i-a_k+a_k-a_j\\
\hspace{5.7em}=mn_{i,k}+mn_{k,j}
\]
因为题目要求唯一答案,\(mn_{i,j}\)要尽可能大
所以
\[mn_{i,j}=\max\limits_{k=1}^{n} mn_{i,k}+mn_{k,j}
\]
同理
\[mx_{i,j}=\min\limits_{k=1}^{n} mx_{i,k}+mx_{k,j}
\]
step3
当\(A+B>a_i+a_j\)时
\[A+B>a_i+a_j\\
\hspace{3em}A-a_i+B-a_j>0\rightarrow mn_{A,i}+mn_{B,j}>0\\
\hspace{3em}A-a_j+B-a_i>0\rightarrow mn_{A,j}+mn_{B,i}>0\\
\]
\(A+B<a_i+a_j\)类似
\[A+B<a_i+a_j\\
\hspace{3em}A-a_i+B-a_j<0\rightarrow mx_{A,i}+mx_{B,j}<0\\
\hspace{3em}A-a_j+B-a_i<0\rightarrow mx_{A,j}+mx_{B,i}<0\\
\]
\(A+B=a_i+a_j\)有点不同。因为既要满足\(mx\)相等,又要满足\(mn\)相等。
\[\hspace{-15em}\textcircled{1}\\
A+B=a_i+a_j\\
\hspace{8.2em}{A-a_i+B-a_j=0}\rightarrow{mx_{A,i}=mn_{A,i},mx_{B,j}=mn_{B,j}}\\
\hspace{-4.3em}{{A,i}+{B,j}=0}
\]
\[\hspace{-15em}\textcircled{2}\\
A+B=a_i+a_j\\
\hspace{8.2em}{A-a_j+B-a_i=0}\rightarrow{mx_{A,j}=mn_{A,j},mx_{B,i}=mn_{B,i}}\\
\hspace{-4.3em}{{A,j}+{B,i}=0}
\]
\(\because mx_{i,j}=mn_{i,j}\)
\(\therefore\)取\(mx\) \(mn\)都行
step4
#include<bits/stdc++.h>
using namespace std;
const int N=55;
char g[N][N];
int mx[N][N],mn[N][N];
int n,A,B;
void csh()
{for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(g[i][j]=='+')mx[i][j]=2,mn[i][j]=1;if(g[i][j]=='-')mx[i][j]=-1,mn[i][j]=-2;if(g[i][j]=='=')mx[i][j]=mn[i][j]=0;if(g[i][j]=='?')mx[i][j]=2,mn[i][j]=-2;if(i==j)mx[i][j]=mn[i][j]=0;}}
}
int main()
{cin>>n>>A>>B;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){cin>>g[i][j];}}csh();for(int k=1;k<=n;k++){ for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){mn[i][j]=max(mn[i][j],mn[i][k]+mn[k][j]);mx[i][j]=min(mx[i][j],mx[i][k]+mx[k][j]);}}}int c1=0,c2=0,c3=0;for(int i=1;i<=n;i++){for(int j=i+1;j<=n;j++){if(i==A||i==B||j==A||j==B)continue;if(mn[A][i]+mn[B][j]>0||mn[A][j]+mn[B][i]>0)c1++;if(mx[A][i]+mx[B][j]<0||mx[A][j]+mx[B][i]<0)c3++;if(mn[A][i]==mx[A][i]&&mn[B][j]==mx[B][j]&&mn[A][i]+mn[B][j]==0)c2++;else if(mn[A][j]==mx[A][j]&&mn[B][i]==mx[B][i]&&mn[A][j]+mn[B][i]==0)c2++;}}cout<<c1<<' '<<c2<<' '<<c3;return 0;
}