题目描述
B 国在耗资百亿元之后终于研究出了新式武器——连环阵(Zenith Protected Linked Hybrid Zone)。传说中,连环阵是一种永不停滞的自发性智能武器。但经过 A 国间谍的侦察发现,连环阵其实是由 M 个编号为 1, 2,……, M 的独立武器组成的。最初,1 号武器发挥着攻击作用,其他武器都处在无敌自卫状态。以后,一旦第 i 号武器被消灭,1 秒种以后第 i+1 号武器就自动从无敌自卫状态变成攻击状态。当第 M 号武器被消灭以后,这个造价昂贵的连环阵就被摧毁了。
为了彻底打击 B 国科学家,A 国军事部长打算用最廉价的武器——炸弹来消灭连环阵。经过长时间的精密探测,A 国科学家们掌握了连环阵中 M 个武器的平面坐标,然后确定了 n 个炸弹的平面坐标并且安放了炸弹。每个炸弹持续爆炸时间为 5 分钟。在引爆时间内,每枚炸弹都可以在瞬间消灭离它平面距离不超过 k 的、处在攻击状态的 B 国武器。和连环阵类似,最初 号炸弹持续引爆 5 分钟时间,然后
号炸弹持续引爆 5 分钟时间,接着
号炸弹引爆……以此类推,直到连环阵被摧毁。
显然,不同的序列 ,…… 消灭连环阵的效果也不同。好的序列可以在仅使用较少炸弹的情况下就将连环阵摧毁;坏的序列可能在使用完所有炸弹后仍无法将连环阵摧毁。现在,请你决定一个最优序列
,…… 使得在第
号炸弹引爆的时间内连环阵被摧毁。这里的 x 应当尽量小。
输入格式
第一行包含三个整数:M、n 和 k,分别表示 B 国连环阵由 M 个武器组成,A 国有 n 个炸弹可以使用,炸弹攻击范围为 k。以下 M 行,每行由一对整数 ,
组成,表示第 i 号武器的平面坐标。再接下来 n 行,每行由一对整数
,
组成,表示第 i 号炸弹的平面坐标。输入数据保证随机、无误、并且必然有解。
输出格式
一行包含一个整数 x,表示实际使用的炸弹数。
样例 :
样例输入
4 3 6
0 6
6 6
6 0
0 0
1 5
0 3
1 1
### 样例输出 #1
2
解答:
#include <bits/stdc++.h>
using namespace std;
//Start
typedef long long ll;
typedef double db;
#define mp(a,b) make_pair((a),(b))
#define x first
#define y second
#define be(a) (a).begin()
#define en(a) (a).end()
#define sz(a) int((a).size())
#define pb(a) push_back(a)
#define R(i,a,b) for(int i=(a),I=(b);i<I;i++)
#define L(i,a,b) for(int i=(b)-1,I=(a)-1;i>I;i--)
const int iinf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f;
//Data
const int N=1e2;
int m,n,k;
pair<int,int> a[N],b[N];
bitset<N> con[N];
#define f(x) ((x)*(x))
//Dfs
bitset<N> e[N],vis;
int nex[N][N+1],mn[N+1],mat[N],ans;
bool match(int s){ // 匈牙利匹配
R(i,0,n)if(e[s][i]&&!vis[i]){
vis[i]=true;
if(!~mat[i]||match(mat[i]))
return mat[i]=s,true;
}
return false;
}
void dfs(int j,int s){
if(ans<=s+mn[j]) return; //A*
if(j==m) return void(ans=s);
int cmat[N]; copy(mat,mat+n,cmat); // 这里的 cmat 你要是设为全局变量就死了,我在这里死了 2 个小时
L(J,j+1,m+1){
R(i,0,n) con[i][j]&&nex[i][j]>=J&&(e[s][i]=true);
R(i,0,n) vis[i]=false; match(s)?dfs(J,s+1):void();
R(i,0,n) con[i][j]&&nex[i][j]>=J&&(e[s][i]=false); //莫忘回溯
copy(cmat,cmat+n,mat);
}
}
//Main
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>m>>n>>k;
R(j,0,m) cin>>a[j].x>>a[j].y;
R(i,0,n) cin>>b[i].x>>b[i].y;
R(i,0,n)R(j,0,m) con[i][j]=(f(a[j].x-b[i].x)+f(a[j].y-b[i].y)<=f(k));
R(i,0,n) fill(nex[i],nex[i]+m+1,-1);
R(i,0,n)L(j,0,m) con[i][j]&&(nex[i][j]=max(j+1,nex[i][j+1]));
R(j,0,m) mn[j]=iinf;
L(j,0,m)R(i,0,n) con[i][j]&&(mn[j]=min(mn[j],mn[nex[i][j]]+1));
fill(mat,mat+n,-1),ans=min(n,m),dfs(0,0);
cout<<ans<<'\n';
return 0;
}