SOJ 8064 Whack the Groundhog

Description

You are playing the game ‘Whack the Groundhog’ with your little nephew. Considering your terrible performance, you decide to get some help to establish your glory image in front of him. The first is to collect some necessary data. After a few times of practicing, you get to know exactly when the groundhogs will get up. Easy job, isn’t it? However, it seems that this is not enough, how to move your hammer is really a problem, and you’d like to solve it by computer.

To make things easier, we assume that the game is playing on one N × Nrectangle grid, means that there are N × N holes in the land. The hammer is on the top left corner at the zero second (the beginning of the game). You can move the hammer to the up, down, right or left cell, at the speed of one cell per second, while whacking the groundhogs takes zero second. Knowing that when and where the groundhogs are getting up, your task here is to calculate the maximum possible number of groundhogs that can be whacked. Please note that only when a groundhog gets up and at the same time the hammer is on the same cell with that groundhog, it gets whacked. You can also keep the hammer for any time on any cell.

Input

The first line of input will be a positive integer TT ≤ 10, indicating T test cases follow.

For each test case, the first line of input will be a positive integer NN ≤ 10, indicating the size of the grid. The second line of input will be a positive integer CC ≤ 1000, then C lines follow, each line contain 3 integers XY and S, separated by one blank space. X and Y indicating the row and column of the specific groundhog getting up, and S indicating the second of the groundhog getting up, both XY and S are counting from 0, 0 ≤ XY < N, 0 ≤ S ≤ 1000.

 
Output 

For each test case, output one integer on one line, indicating the maximum possible number of groundhogs that can be whacked.

Sample Input
1
2
4
0 0 0
0 1 1
1 0 1
1 0 2
Sample Output
3
Hint

In the example above, the optimal solution should be as follow.

1.        Whacked the groundhog in row 0 and column 0 at time 0;

2.        Move the hammer to row 1 and column 0, whacked the groundhog there at time 1;

3.        Keep the hammer at row 1 and column 0, whacked the groundhog there at time 2.

Problem Source: 庆五一,迎省赛——gdcpc2010

分析:

dp[t][i][j]:t代表时间,(i,j)代表坐标。

挺简单的一个动规,一开始思路错了,后来把思路改过来,初始化方式又错了……→_→

之前我把数组所有的元素都初始化为0,WA。

后来改的是:如果第0时刻(0,0)位置有地鼠,dp[0][0][0]就初始化为1,否则初始化为0,其余均初始化为负无穷。

若dp[t][i][j]为负数,则代表t时刻锤子无法到达(i,j)位置。

因为第0时刻锤子在(0, 0)位置,且一个单位时间只能四方向移动一个格。如果全部初始化为0,就意味着第0时刻锤子可以在任意位置,这显然是不对的。

View Code
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 
 8 const int MAXN = 20;
 9 const int MAXS = 1010;
10 const int INF = 2147483645;
11 const int dx[] = { 0, 0, 0, -1, 1 };
12 const int dy[] = { 0, -1, 1, 0, 0 };
13 
14 struct node
15 {
16     int x, y;
17     int t;
18 };
19 
20 node D[MAXS];
21 int dp[MAXS][MAXN][MAXN];
22 int vis[MAXS][MAXN][MAXN];
23 int N, C, maxT;
24 
25 bool check( int x, int y )
26 {
27     return x >= 0 && x < N && y >= 0 && y < N;
28 }
29 
30 void solved()
31 {
32     memset( dp, 0, sizeof(dp) );
33 
34     for ( int i = 0; i < N; ++i )
35         for ( int j = 0; j < N; ++j )
36             dp[0][i][j] = -INF;
37 
38     dp[0][0][0] = vis[0][0][0];
39 
40     int ans = vis[0][0][0];
41     for ( int t = 1; t <= maxT + 1; ++t )
42     {
43         for ( int i = 0; i < N; ++i )
44             for ( int j = 0; j < N; ++j )
45                 dp[t][i][j] = -INF;
46         for ( int i = 0; i < N; ++i )
47             for ( int j = 0; j < N; ++j )
48             {
49                 for ( int k = 0; k < 5; ++k )
50                 {
51                     int tpx = i + dx[k];
52                     int tpy = j + dy[k];
53                     if ( check( tpx, tpy ) )
54                     {
55                         dp[t][i][j] = max( dp[t][i][j], dp[t - 1][tpx][tpy] + vis[t][i][j] );
56                         ans = max( ans, dp[t][i][j] );
57                     }
58                 }
59             }
60     }
61 
62     printf( "%d\n", ans );
63     return;
64 }
65 
66 int main()
67 {
68     int T;
69     scanf( "%d", &T );
70     while ( T-- )
71     {
72         scanf( "%d%d", &N, &C );
73         memset( vis, 0, sizeof(vis) );
74         maxT = 0;
75         for ( int i = 0; i < C; ++i )
76         {
77             scanf( "%d%d%d", &D[i].x, &D[i].y, &D[i].t );
78             maxT = max( maxT, D[i].t );
79             vis[ D[i].t ][ D[i].x ][ D[i].y ] = 1;
80         }
81 
82         solved();
83     }
84     return 0;
85 }
原文地址:https://www.cnblogs.com/GBRgbr/p/3052323.html