题解 | #数字匹配#
数字匹配
https://ac.nowcoder.com/acm/contest/11217/C
C.数字匹配
如果一个数对 , 存在重合位数大于 的子串,那么在所有 , 中,一定存在从第 位到第 位相互匹配的数对。
令 为拥有恰好 个 的二进制串,那么 , 从第 位到第 位相互匹配即可视作 。
于是我们可以设计一个算法:对 , 尝试用上述过程匹配,如果失败则尝试对 , 和 , 匹配,直到某个数的长度小于 。
这么做显然会 TLE,但我们可以用记忆化搜索优化,把已计算的结果存储下来。
时空复杂度 ,然而记搜常数巨大,跑得不见得比 快。
#include <bits/stdc++.h>
using namespace std;
#define b(x) (1<<((x)-1))
int i,j,n,m,t,res,f[2050][2050],msk;
int dfs(int x,int y){
if(b(m)>x||b(m)>y)return 0;
if(~f[x][y])return f[x][y];
if(((x&msk)==(y&msk))) return f[x][y]=1;
else return f[x][y]=(dfs(x>>1,y)|dfs(x,y>>1));
}
int main() {
memset(f,-1,sizeof(f));
cin>>n>>m;
msk=b(m+1)-1;
for(i=1;i<=n;i++){
for(j=i+1;j<=n;j++){
res+=dfs(i,j);
}
}
cout<<res;
}