题意:给定一个N*N的矩阵, 然后在这个矩阵的每个格子在任意时间会出现一个鼹鼠,这个出现
出现鼹鼠的时间是输出信息所确定的. 现在你手里有一把锤子能够去锤这些鼹鼠. 你能
够移动锤子,移动的两点之间的距离不能超过d,且中心在这条路径上的鼹鼠到都要受到
打击. 每个鼹鼠出现的时间值维持一秒钟. 现在问在一次游戏中最多打到多少鼹鼠
1 /* 2 dp 3 题意:给定一个N*N的矩阵, 然后在这个矩阵的每个格子在任意时间会出现一个鼹鼠,这个出现 4 出现鼹鼠的时间是输出信息所确定的. 现在你手里有一把锤子能够去锤这些鼹鼠. 你能 5 够移动锤子,移动的两点之间的距离不能超过d,且中心在这条路径上的鼹鼠到都要受到 6 打击. 每个鼹鼠出现的时间值维持一秒钟. 现在问在一次游戏中最多打到多少鼹鼠 7 思路:一开始状态定义正确,但是思路有问题,不能处理 k-1时刻 到 k时刻 的鼹鼠(也就是没法判断这“两种”鼹鼠的距离是否小于<=d) 8 9 */ 10 #include<algorithm> 11 #include<iostream> 12 #include<string.h> 13 #include<stdlib.h> 14 #include<stdio.h> 15 #include<math.h> 16 #include<queue> 17 #include<stack> 18 #include<map> 19 #include<set> 20 using namespace std; 21 typedef long long int64; 22 //typedef __int64 int64; 23 typedef pair<int64,int64> PII; 24 #define MP(a,b) make_pair((a),(b)) 25 const int inf = 0x3f3f3f3f; 26 const double pi=acos(-1.0); 27 const int dx[]={1,-1,0,0}; 28 const int dy[]={0,0,1,-1}; 29 const double eps = 1e-8; 30 const int maxm = 1005; 31 const int maxn = 35; 32 33 int mat[ 12 ][ maxn ][ maxn ]; 34 int dp[ 12 ][ maxn ][ maxn ]; 35 //dp[t][x][y]:当t时刻,锤子打了xy的鼹鼠的MaxVal 36 int d; 37 38 int dis2( int x1,int y1,int x2,int y2 ){ 39 return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2); 40 } 41 42 int Count( int cur_ti,int x1,int y1,int x2,int y2 ){ 43 int cnt = 0; 44 if( x1==x2 ){ 45 if( y1>y2 ) swap( y1,y2 ); 46 for( int i=y1;i<=y2;i++ ){ 47 cnt += mat[ cur_ti ][ x1 ][ i ]; 48 } 49 return cnt; 50 } 51 if( y1==y2 ){ 52 if( x1>x2 ) swap( x1,x2 ); 53 for( int i=x1;i<=x2;i++ ){ 54 cnt += mat[ cur_ti ][ i ][ y1 ]; 55 } 56 return cnt; 57 } 58 if( x1>x2 ){ 59 swap( x1,x2 ); 60 swap( y1,y2 ); 61 } 62 for( int i=x1;i<=x2;i++ ){ 63 if( ((i-x1)*y2+(x2-i)*y1)%(x2-x1)==0 ){ 64 cnt += mat[ cur_ti ][ i ][ ((i-x1)*y2+(x2-i)*y1)/(x2-x1) ]; 65 } 66 } 67 return cnt; 68 } 69 70 int DP( int n,int MaxTi ){ 71 n+=10; 72 int ans = 0; 73 for( int i=2;i<=MaxTi+1;i++ ){ 74 for( int x=0;x<n;x++ ){ 75 for( int y=0;y<n;y++ ){ 76 dp[ i ][ x ][ y ] = 0; 77 int Ymax = min( y+d,n-1 ); 78 int Ymin = max( 0,y-d ); 79 int Xmax = min( x+d,n-1 ); 80 int Xmin = max( 0,x-d ); 81 for( int x2=Xmin;x2<=Xmax;x2++ ){ 82 for( int y2=Ymin;y2<=Ymax;y2++ ){ 83 if( dis2( x,y,x2,y2 )<=d*d ){ 84 dp[i][x][y] = max( dp[i][x][y],dp[i-1][x2][y2]+Count( i-1,x,y,x2,y2 ) ); 85 } 86 } 87 } 88 ans = max( ans,dp[ i ][ x ][ y ] ); 89 } 90 } 91 } 92 return ans; 93 } 94 95 int main(){ 96 int n,m; 97 while( scanf("%d%d%d",&n,&d,&m)==3 ){ 98 if( n==0&&d==0&&m==0 ) 99 break; 100 memset( mat,0,sizeof( mat ) ); 101 int MaxTi = 0; 102 for( int i=0;i<m;i++ ){ 103 int x,y,t; 104 scanf("%d%d%d",&x,&y,&t); 105 x += 5; 106 y += 5; 107 MaxTi = max( MaxTi,t ); 108 mat[ t ][ x ][ y ] = 1; 109 } 110 int ans = DP( n,MaxTi ); 111 printf("%d\n",ans); 112 } 113 return 0; 114 }