POJ-3034 Whac-a-Mole DP (trick很坑爹)

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

  此题的状态方程很容易想出来,以时间为阶段划分,然后地图为状态,f[k][i][j]=Max{ f[k-1][x][y]+t | t=sum( map[k][p][q] && (p,q)在线段(i,j)-(x,y)上 }。

  转移的时候用点小技巧就可以了,就是先把通方向上的单位整数向量求出来,在更新的时候逐个用 n*单位整数向量 (n满足距离不超过d) 来更新f[k][i][j],最后遍历一遍最值。

  此题有一个很坑的trick:hammer可以在正整数坐标轴的外面,很坑啊有不有!!!足足贡献了4个WA= =

 1 //STATUS:C++_AC_157MS_216KB

 2 #include<stdio.h>

 3 #include<stdlib.h>

 4 #include<string.h>

 5 #include<math.h>

 6 #include<iostream>

 7 #include<string>

 8 #include<algorithm>

 9 #include<vector>

10 #include<queue>

11 #include<stack>

12 using namespace std;

13 #define LL __int64

14 #define pii pair<int,int>

15 #define Max(a,b) ((a)>(b)?(a):(b))

16 #define Min(a,b) ((a)<(b)?(a):(b))

17 #define mem(a,b) memset(a,b,sizeof(a))

18 #define lson l,mid,rt<<1

19 #define rson mid+1,r,rt<<1|1

20 const int N=32,INF=0x3f3f3f3f,MOD=100000000;

21 const double DNF=100000000000;

22 

23 int dx[4]={1,1,-1,-1},dy[4]={1,-1,-1,1};

24 int f[2][N][N],ma[11][N][N],lxy[N][2],cou;

25 int n,d,m;

26 

27 int gcd(int a,int b){return b?gcd(b,a%b):a;}

28 

29 int dist(int x1,int y1,int x2,int y2)

30 {

31     return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);

32 }

33 

34 int main()

35 {

36  //   freopen("in.txt","r",stdin);

37     int i,j,k,ans,t,x,y,p,end,dir,nx,ny,q;

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

39     {

40         end=-INF;

41         mem(ma,0);

42         mem(f,0);

43         while(m--){

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

45             if(t>end)end=t;

46             ma[t][x+d][y+d]=1;

47         }

48         for(cou=x=0;x<=d;x++)

49             for(y=0;y<=d;y++){

50                 if(dist(x,y,0,0)>d*d)continue;

51                 t=gcd(x,y);

52                 if(t<=1 && x+y){

53                     lxy[cou][0]=x;

54                     lxy[cou++][1]=y;

55                 }

56             }

57         n+=2*d;

58         d*=d;

59         for(k=p=1;k<=end;k++,p=!p){

60             for(i=0;i<n;i++){

61                 for(j=0;j<n;j++){

62                     f[p][i][j]=Max(f[p][i][j],f[!p][i][j]+ma[k][i][j]);

63                     for(dir=0;dir<4;dir++){

64                         for(q=0;q<cou;q++){

65                             x=lxy[q][0]*dx[dir];

66                             y=lxy[q][1]*dy[dir];

67                             nx=i+x,ny=j+y;

68                             for(t=ma[k][i][j];dist(nx,ny,i,j)<=d

69                             && nx>=0&&nx<n && ny>=0&&ny<n;nx+=x,ny+=y){

70                                 t+=ma[k][nx][ny];

71                                 f[p][nx][ny]=Max(f[p][nx][ny],f[!p][i][j]+t);

72                             }

73                         }

74                     }

75                 }

76             }

77         }

78         for(ans=-INF,i=0,p=!p;i<n;i++)

79             for(j=0;j<n;j++)

80                 if(f[p][i][j]>ans)ans=f[p][i][j];

81 

82         printf("%d\n",ans);

83     }

84     return 0;

85 }

 

你可能感兴趣的:(poj)