|
属于状态型的动态规划,特难搞的那一类,状态一多,转换的时候难免遗漏一两个。 这题还算,借助数据搞出来了,漏了两个转移,结果一组数据过不了。 后来加上就AC了,时间还行,32MS。
思路: 从左往右开始放矩形,假设现在准备摆放第i列之后的矩形。 实际上我们只关注第i-1列是怎么摆的,前面怎么摆都无所谓。 所以, 第i列牛的状态 + 第i-1列摆放的状态 -> 第i列摆放的状态 摆放的状态有五种: 1. 光上面有 2. 光下面有 3. 上下都有但不属于同一个矩形 4. 空 5. 上下都有并且属于同一个矩形 牛的状态有四种,就是1~4。
然后就看怎么推了,详见代码。 代码中对状态的定义也是按照上面的顺序。
在网上找解题报告,发现有的大牛代码很短很快很牛逼!佩服!
ps: 一开始这份代码用g++和gcc提交是WA的,但c++提交可以AC。 我在本地测试了一下,发现g++和gcc编译后,数据是跑得过的。我的gcc版本很高,是4.3.3。 不知道是北大的网站有问题,还是我的代码有问题。不过后者可能性大很多。 后来,我把inline去掉(#define inline),再用g++、gcc提交,就过了! 很想不通,写其他代码的时候,也是gcc编译的,不都是这样写 inline 的吗,也没见出什么问题,也不可能出问题。 所以希望高手给指点一下!谢谢!
代码:
#include <stdio.h>
#include <stdlib.h>

 enum {
UP, DOWN, UPDOWN, SPACE, CONN
};

#define MAX_N 1024
#define MAX_AREA (15000000 * 2)

#define inline

 struct cow_node {
int y, x;
};
int dp[2][5][MAX_N], (*cur)[MAX_N], (*pre)[MAX_N];
struct cow_node cows[MAX_N];
int N, K, B, max_k;

int cmp(const void *a, const void *b)
  {
return ((struct cow_node *)a)->x - ((struct cow_node *)b)->x;
}

inline int min(int a, int b)
  {
return a < b ? a : b;
}

inline void swap(void *a, void *b)
  {
void *t = *(void **)a;
*(void **)a = *(void **)b;
*(void **)b = t;
}

inline void init(int (*t)[MAX_N])
  {
int i;

for (i = 0; i <= max_k + 4; i++)
t[0][i] = t[1][i] = t[2][i] = t[3][i] = t[4][i] = MAX_AREA;
}

#if 0
inline void dump(int (*t)[MAX_N], int ptn)
  {
#define dbp printf
int i, j;
 const char *strs[] = {
"up", "down", "updown", "space", "conn"
};
 const char *ptns[] = {
"*\n\n", "\n*\n", "*\n*\n", "\n\n"
};

dbp("---------\n%s", ptns[ptn]);
 for (i = 0; i < 5; i++) {
dbp("%s: ", strs[i]);
for (j = 0; j <= max_k; j++)
dbp("%d->%d ", j, t[i][j]);
dbp("\n");
}
dbp("\n");
#undef dbp
}
#else
#define dump( ) {}
#endif

inline void calc(int ptn, int space_cnt)
  {
int i;

#define UPDATE(_from, _to, _a_used, _k_used) \
cur[_to][i + _k_used] = min(cur[_to][i + _k_used], pre[_from][i] + _a_used)
#define CASE(_ptn, _code) \
 if (ptn == _ptn) { \
for (i = 0; i <= max_k; i++) \
_code \
}
init(cur);

 CASE(UP, {
UPDATE(UP, UP, 1, 0);
UPDATE(UPDOWN, UP, 1, 0);
UPDATE(UPDOWN, UPDOWN, 2, 0);
UPDATE(DOWN, UP, 1, 1);
UPDATE(DOWN, UPDOWN, 2, 1);
UPDATE(CONN, CONN, 2, 0);
UPDATE(CONN, UP, 1, 1);
UPDATE(SPACE, UP, 1, 1);
UPDATE(SPACE, CONN, 2, 1);
});

 CASE(DOWN, {
UPDATE(DOWN, DOWN, 1, 0);
UPDATE(UPDOWN, DOWN, 1, 0);
UPDATE(UPDOWN, UPDOWN, 2, 0);
UPDATE(UP, DOWN, 1, 1);
UPDATE(UP, UPDOWN, 2, 1);
UPDATE(CONN, CONN, 2, 0);
UPDATE(CONN, DOWN, 1, 1);
UPDATE(SPACE, DOWN, 1, 1);
UPDATE(SPACE, CONN, 2, 1);
});

 CASE(UPDOWN, {
UPDATE(UP, UPDOWN, 2, 1);
UPDATE(UPDOWN, UPDOWN, 2, 0);
UPDATE(DOWN, UPDOWN, 2, 1);
UPDATE(CONN, CONN, 2, 0);
UPDATE(SPACE, CONN, 2, 1);
UPDATE(SPACE, UPDOWN, 2, 2);
});

 CASE(SPACE, {
UPDATE(UP, SPACE, 0, 0);
UPDATE(UP, UP, space_cnt, 0);
UPDATE(DOWN, SPACE, 0, 0);
UPDATE(DOWN, DOWN, space_cnt, 0);
UPDATE(UPDOWN, SPACE, 0, 0);
UPDATE(UPDOWN, UPDOWN, space_cnt*2, 0);
UPDATE(UPDOWN, UP, space_cnt, 0);
UPDATE(UPDOWN, DOWN, space_cnt, 0);
UPDATE(CONN, SPACE, 0, 0);
UPDATE(CONN, CONN, space_cnt*2, 0);
UPDATE(SPACE, SPACE, 0, 0);
});

#undef UPDATE
#undef CASE

dump(cur, ptn);

swap(&cur, &pre);
}


int main()
  {
int i;

freopen("e:\\test\\in.txt", "r", stdin);

scanf("%d%d%d", &N, &K, &B);
for (i = 0; i < N; i++)
scanf("%d%d", &cows[i].y, &cows[i].x);
qsort(cows, N, sizeof(cows[0]), cmp);

cur = dp[0];
pre = dp[1];
max_k = 2;
init(pre);
pre[SPACE][0] = 0;
 for (i = 0; i < N; ) {
max_k = min(i + 2, K);
if (i && cows[i - 1].x + 1 != cows[i].x)
calc(SPACE, cows[i].x - cows[i - 1].x - 1);
 if (i + 1 < N && cows[i + 1].x == cows[i].x) {
calc(UPDOWN, 0);
i += 2;
 } else {
calc(cows[i].y == 1 ? UP : DOWN, 0);
i++;
}
}
calc(SPACE, 0);

printf("%d\n", pre[SPACE][K]);

return 0;
}


|