poj 3034 Whac-a-Mole(dp)

来源:互联网 发布:宫崎骏隐喻知乎 编辑:程序博客网 时间:2024/05/18 19:46

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

【题意】就是打鼹鼠游戏。n*n个洞,给出m个鼹鼠开始出现的位置和时间,每个鼹鼠出现的时长为1s。一开始锤子可放在任意位置,每秒移动的距离为0~d(1<=d<=5)

锤子只能直线移动,可以把在线段(包括端点)上的鼹鼠都打掉。锤子放置的位置只能是整数点。

【思路】可以很容易写出状态转移方程  dp[t][i][j]=max(dp[t-1][x][y]+walk(x,y,i,j)),dp[t][i][j]表示的是第t秒后锤子放在(i,j)最多打的鼹鼠,walk(x,y,i,j,t)表示锤子

从(x,y)->(i,j)在第t秒打到的鼹鼠。walk写的很纠结。。一开始想预处理出所有的walk。。发现既不好搞,又没意义。。

注意:锤子可以放在游戏界面之外。。

【代码】

/*只能说这个题太好了=_=*/#include<cstdio>#include<cstring>#include<iostream>#include<cmath>using namespace std;int dp[15][30][30];int abs(int a){    return a>0?a:-a;}int mp[15][30][30];int gcd(int a,int b){    if(b==0)return a;    return gcd(b,a%b);}int walk(int x,int y,int i,int j,int time){    int cnt=0;    int dx=i-x,dy=j-y;    if(dx==0&&dy==0)return mp[time][x][y];    int g;    if(dx==0||dy==0)        g=abs(dx+dy);    else g=gcd(abs(dx),abs(dy));    dx=dx/g;dy=dy/g;    for(int i=0;i<=g;i++)        cnt+=mp[time][dx*i+x][dy*i+y];    return cnt;}int main(){    int n,d,m;    while(scanf("%d%d%d",&n,&d,&m)!=EOF)    {        if(n+d+m==0)break;        memset(mp,0,sizeof(mp));        int mtime=0;        for(int i=0;i<m;i++)        {            int x,y,time;            scanf("%d%d%d",&x,&y,&time);            mp[time][x+d][y+d]=1;//x+d,y+d处理锤子走直线出游戏界面的情况            mtime=max(mtime,time);        }        memset(dp,0,sizeof(dp));        n+=2*d;        //cout<<"f"<<endl;        for(int t=1;t<=mtime;t++)            for(int i=0;i<n;i++)                for(int j=0;j<n;j++)                {                   // cout<<"f2"<<endl;                    int top=max(0,i-d),bot=min(n-1,i+d);                    int left=max(0,j-d),right=min(n-1,j+d);                    for(int x=top;x<=bot;x++)                    {                        for(int y=left;y<=right;y++)                        {                            if((x-i)*(x-i)+(y-j)*(y-j)>d*d)continue;                            //cout<<"t="<<t<<ends<<x<<ends<<y<<" to "<<i<<ends<<j<<endl;                            dp[t][i][j]=max(dp[t][i][j],dp[t-1][x][y]+walk(x,y,i,j,t));                        }                    }                }        int ans=0;        for(int i=0;i<n;i++)            for(int j=0;j<n;j++)                ans=max(ans,dp[mtime][i][j]);        printf("%d\n",ans);    }    return 0;}



0 0