不合法方案的花费一定比最优解大
有了这条隐含信息, 直接搜索, 方法如下 ,
- 按顺序给每只兔子安排围墙,
- 设当前搜到了 只兔子, 有两个选择.
- 扩张前面所存在的围栏
- 只围住自己
加上 最优化剪枝 即可 .
#include<bits/stdc++.h>
#define reg register
int read(){
char c;
int s = 0, flag = 1;
while((c=getchar()) && !isdigit(c))
if(c == '-'){ flag = -1, c = getchar(); break ; }
while(isdigit(c)) s = s*10 + c-'0', c = getchar();
return s * flag;
}
const int maxn = 25;
int M;
int K;
int N;
int Ans;
int min_x[maxn];
int min_y[maxn];
int max_x[maxn];
int max_y[maxn];
struct Rabbit{ int x, y; } A[maxn];
void DFS(int k, int cnt, int sum){
if(sum >= Ans) return ;
if(k > N){ Ans = sum; return ; }
if(cnt < K){
min_x[cnt+1] = max_x[cnt+1] = A[k].x;
min_y[cnt+1] = max_y[cnt+1] = A[k].y;
DFS(k+1, cnt+1, sum + 4);
}
if(k == 1) return ;
for(reg int i = 1; i <= cnt; i ++){
int tx = A[k].x, ty = A[k].y;
int t_1 = min_x[i], t_2 = min_y[i], t_3 = max_x[i], t_4 = max_y[i];
int tmp = 2*(max_x[i]-min_x[i]+max_y[i]-min_y[i]);
min_x[i] = std::min(tx, min_x[i]);
min_y[i] = std::min(ty, min_y[i]);
max_x[i] = std::max(tx, max_x[i]);
max_y[i] = std::max(ty, max_y[i]);
tmp = 2*(max_x[i]-min_x[i]+max_y[i]-min_y[i]) - tmp;
DFS(k+1, cnt, sum + tmp);
min_x[i] = t_1, min_y[i] = t_2, max_x[i] = t_3, max_y[i] = t_4;
}
}
int main(){
M = read(); K = read(); N = read();
for(reg int i = 1; i <= N; i ++)
A[i].x = read(), A[i].y = read();
Ans = 0x3f3f3f3f;
DFS(1, 0, 0);
printf("%d
", Ans);
return 0;
}