原题链接
原本以为要剪枝剪半天的一道题,结果因为数据实在是太水,裸的爆搜就能过了。。
刚打算写个(HASH)去重,结果看时间不够就随便交一发,然后就(A)了。。(捂脸
爆搜就直接搜每个点在哪个矩阵里,同时更新答案即可。
因为过了,所以就懒得写剪枝和去重了
#include<cstdio>
using namespace std;
const int N = 55;
struct poi {
int x, y;
};
poi a[N];
struct squ {
int x_mi, x_ma, y_mi, y_ma, s;
bool p;
squ() { x_mi = y_mi = 1e9; }
};
squ jz[5];
int n, k, mi = 1e9;
inline int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c < '0' || c > '9'; c = getchar())
p |= c == '-';
for (; c >= '0' && c <= '9'; c = getchar())
x = x * 10 + c - '0';
return p ? -x : x;
}
inline void ckmaxn(int &x, int y) { if (x < y) x = y; }
inline void ckminn(int &x, int y) { if (x > y) x = y; }
inline bool judge()
{
for (int i = 1; i < k; i++)
for (int j = i + 1; j <= k; j++)
{
if (!jz[i].p || !jz[j].p)
continue;
if (jz[i].x_ma >= jz[j].x_mi && jz[j].x_ma >= jz[i].x_mi && jz[i].y_ma >= jz[j].y_mi && jz[j].y_ma >= jz[i].y_mi)
return false;
}
return true;
}
void dfs(int nw, int s)
{
if (s >= mi)
return;
if (nw > n)
{
mi = s;
return;
}
for (int i = 1; i <= k; i++)//搜这个点在哪个矩阵
{
if (a[nw].x <= jz[i].x_ma && a[nw].y <= jz[i].y_ma && a[nw].x >= jz[i].x_mi && a[nw].y >= jz[i].y_mi)//如果在原本范围就直接扔进去,其实这里可以加一个剪枝,因为已经在一个矩阵里的点显然不能给其它矩阵
dfs(nw + 1, s);
else//如果在该矩阵之外就扩展这个矩阵
{
squ o = jz[i];
ckmaxn(jz[i].x_ma, a[nw].x);
ckmaxn(jz[i].y_ma, a[nw].y);
ckminn(jz[i].x_mi, a[nw].x);
ckminn(jz[i].y_mi, a[nw].y);
jz[i].p = 1;//判断是否已经覆盖了点,使没有覆盖点的矩阵在judge中跳过
if (judge())//判断是否有矩阵重合
dfs(nw + 1, s - o.s + (jz[i].s = (jz[i].x_ma - jz[i].x_mi) * (jz[i].y_ma - jz[i].y_mi)));
jz[i] = o;
}
}
}
int main()
{
int i;
n = re(); k = re();
for (i = 1; i <= n; i++)
a[i].x = re(), a[i].y = re();
dfs(1, 0);
printf("%d", mi);
return 0;
}