POJ 3034 Whac-a-Mole [DP]

题意:略。

思路:第一次写的时候搞复杂了,弄得跟计算几何似的= =

递推公式很好想,就是dp[x2][y2][t] = max(dp[x2][y2][t], dp[x1][y1][t-1] + online(x2, y2, x1, y1)。

其中dp[x2][y2][t]表示在时间点t锤子选择砸到点(x2, y2)处时的最大积分,点(x1, y1)与点(x2, y2)距离不大于d,online函数计算的是以这两点为端点的线段上有几只地鼠。

另外,本题中锤子可以砸到坐标系外面,如果不考虑此种情况会wa。处理方法是,读取坐标时横纵坐标都加5(5为锤子可移动距离d的最大值)。

更多细节见代码即注释。

 1 #include<stdio.h>

 2 #include<iostream>

 3 #include<algorithm>

 4 #include<string.h>

 5 using namespace std;

 6 int dp[32][32][12];

 7 bool mole[32][32][12];

 8 int n, d, m, maxt, mint;

 9 int online(int t,int x1,int y1,int x2,int y2)

10 {

11     int sx = min(x1, x2), ex = max(x1, x2);

12     int sy = min(y1, y2), ey = max(y1, y2);

13     int res = 0;

14     for (int x = sx; x <= ex; x++)

15         for (int y = sy; y <= ey; y++)

16             if (mole[x][y][t] && (y1 - y2) * (x - x2) == (y - y2) * (x1 - x2))

17                 res++;

18     return res;

19 }

20 bool judge(int x1,int y1,int x2,int y2)//判断距离是否不大于d

21 {

22     int tem = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);

23     return tem <= d * d;

24 }

25 int getdp()

26 {

27     memset(dp, 0, sizeof(dp));

28     int res = 0;

29     for (int i = mint; i <= maxt; i++)//枚举时间点

30         for (int x = 0; x < n; x++)

31             for (int y = 0; y <= n; y++)//枚举锤子落点

32             {

33                 int sx = max(x - d, 1), ex = min(x + d, n);

34                 int sy = max(y - d, 1), ey = min(y + d, n);

35                 for (int px = sx; px <= ex; px++)

36                     for (int py = sy; py <= ey; py++) if (judge(x, y, px, py))//枚举锤子上次的合法落点

37                     {

38                         dp[x][y][i+1] = max(dp[x][y][i+1], dp[px][py][i] + online(i, x, y, px, py));

39                         res = max(res, dp[x][y][i+1]);

40                     }

41             }

42     return res;

43 }

44 int main()

45 {

46     //freopen("data.in", "r", stdin);

47     while (~scanf("%d%d%d", &n, &d, &m) && (n | d | m))

48     {

49         memset(mole, 0, sizeof(mole));

50         n += 10;

51         maxt = 0;

52         mint = 0x3f3f3f3f;

53         for (int i = 1; i <= m; i++)

54         {

55             int x, y, t;

56             scanf("%d%d%d",&x, &y, &t);

57             mole[x+5][y+5][t] = 1;

58             maxt = max(maxt, t);

59             mint = min(mint, t);

60         }

61         printf("%d\n",getdp());

62     }

63     return 0;

64 }

 

你可能感兴趣的:(poj)