Poj3034 Whac-a-Mole

题目链接:http://poj.org/problem?id=3034

 

题 意:打地鼠游戏中,你有一个锤子,每一秒钟你可以拿着锤子移动d个单位的距离,掠过的鼠洞中露出的地鼠都会被锤打至,而事先知道从开始时各时间段内出现在老鼠的数量和位置,问题是 从游戏开始至结束时,你最多能打到多少只地鼠,开始时锤子可以在任何位置。

 

动态规划问题,我们把每一秒看成一个状态,则当年时间下,锤子落在各位置上能打到的最多的地鼠为能在一秒内移动至该位置的各位置到达该位置时打到的地鼠数量与出发状态时快打到的地鼠数量之和的最大值。

 

#include<stdio.h> #include<string.h> #include<stdlib.h> #define M 32 typedef struct{ int x,y; }Point; int lenth[M]; Point p[M][1008]; int n,d,m; int dp[2][M][M]; int tmp[M][M]; inline int Max(int a,int b) {return a>b?a:b;} inline int Gcd(int a,int b) {return a?Gcd(b%a,a):b;} inline int Cal(int x,int y,int tx,int ty) { int i,j,ret=0,dx,dy,tp; tp=Gcd(abs(tx-x),abs(ty-y)); dx=(tx-x)/tp; dy=(ty-y)/tp; for(i=x,j=y;i!=tx||j!=ty;i+=dx,j+=dy) ret+=tmp[i][j]; ret+=tmp[tx][ty]; return ret; } int main() { int i,j,x,y,t,dx,dy,ans; //freopen("data.in","r",stdin); //freopen("rest.out","w",stdout); while(scanf("%d%d%d",&n,&d,&m),n){ memset(lenth,0,sizeof(lenth)); for(i=0;i<m;i++){ scanf("%d%d%d",&x,&y,&t); p[t][lenth[t]].x=x+d; p[t][lenth[t]].y=y+d; lenth[t]++; }n+=d+d; memset(dp,0,sizeof(dp)); for(i=0;i<lenth[0];i++) dp[0][p[0][i].x][p[0][i].y]++; for(t=1;t<=10;t++){ for(i=0;i<lenth[t];i++) tmp[p[t][i].x][p[t][i].y]++; for(i=0;i<n;i++){ for(j=0;j<n;j++){ dp[t&1][i][j]=dp[!(t&1)][i][j]+tmp[i][j]; for(dx=-d;dx<=d;dx++){ for(dy=-d;dy<=d;dy++){ if(dx*dx+dy*dy>d*d||!dx&&!dy) continue; x=i+dx,y=j+dy; if(x<0||x>=n||y<0||y>=n) continue; dp[t&1][i][j]=Max(dp[t&1][i][j],dp[!(t&1)][x][y]+Cal(i,j,x,y)); } } } } for(i=0;i<lenth[t];i++) tmp[p[t][i].x][p[t][i].y]--; } ans=0; for(i=0;i<n;i++){ for(j=0;j<n;j++) if(dp[0][i][j]>ans) ans=dp[0][i][j]; } printf("%d/n",ans); } return 0; }

你可能感兴趣的:(Poj3034 Whac-a-Mole)