您的位置:首页 > Web前端 > AngularJS

poj 2836 Rectangular Covering (状态压缩dp~)

2017-11-21 01:05 447 查看
刚看到题目时真没想到是状态压缩,当然我什么想法也没有,果然是我太菜了。。。。后来看了题解还是觉挺清楚的。。。

有个坑!!!

算面积那里,注意矩形边长万一小于1,是需要取整为1的。不然会WA。

#include <stdio.h>
#include <string.h>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
#define MAX_N 20
#define INF 0x3f3f3f

int x[MAX_N], y[MAX_N];

struct Rectangle {
int cover; //点集
int area; //面积

Rectangle(int c, int a) {
cover = c;
area = a;
}

//第几位表示第几个点
void addpoint(int c) { cover |= (1 << c); }
};

//点k在不在i和j组成的矩形中
bool is_in(int i, int j, int k) {
return ((x[i] - x[k]) * (x[j] - x[k]) <= 0) &&
((y[i] - y[k]) * (y[j] - y[k]) <= 0);
}
int dp[1 << 16];

int main(void) {
int n;
while (scanf("%d", &n) == 1 && n) {
int xx, yy;
for (int i = 0; i < n; i++) {
scanf("%d%d", &xx, &yy);
x[i] = xx;
y[i] = yy;
}

vector<Rectangle> V;
//对每个矩形进行初始化
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
Rectangle r((1 << i) | (1 << j),
max((int)abs(x[i] - x[j]), 1) *
max(((int)abs(y[i] - y[j])), 1));

for (int k = 0; k < n; k++) {
if (is_in(i, j, k)) r.addpoint(k);
}

V.push_back(r);
}
}
// dp[i]的含义是包含i个矩形的最小面积
memset(dp, INF, sizeof(dp));
dp[0] = 0;

for (size_t i = 0; i < V.size(); i++) {
for (int state = 0; state < (1 << n); state++) {
int newstate = state | V[i].cover;
//此条件限制了只能从第0个开始dp
if (dp[state] == INF) con
4000
tinue;
if (newstate == state) continue;
dp[newstate] = min(dp[newstate], dp[state] + V[i].area);
}
}

printf("%d\n", dp[(1 << n) - 1]);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: