POJ 3034 简单dp--注意细节

来源:互联网 发布:淘宝汽车服务在哪里 编辑:程序博客网 时间:2024/05/24 05:01

没考虑到锤子可能到达界外一直不过,

从界外也能转移进来,并可能得到更优的结果

想法是简单的,从前一秒的每个状态转移到下一秒的每个状态,状态数比较小,能过

在处理经过时得到几分比较山寨,凑合着吧。。

#include <iostream>#include <cstring>#include <cstdio>#include <cstdlib>#include <vector>using namespace std;#define eps 1e-8int n,d,m;int vis[15][33][33];int dp[15][33][33];inline int count(int sx,int sy,int ex,int ey,int tm){int ret=0;if(sx==ex){if(ey<sy)swap(ey,sy);for(int j=sy;j<=ey;++j)if(vis[tm][sx][j])ret++;}else if(sy==ey){if(ex<sx)swap(ex,sx);for(int i=sx;i<=ex;++i)if(vis[tm][i][sy])ret++;}else{if(ex<sx){swap(sx,ex);swap(sy,ey);}double r=(ey-sy)*1.0/((ex-sx)*1.0);for(int i=0;i+sx<=ex;++i){double ty=i*r+1.0*sy;int inty=ty+eps;if(vis[tm][sx+i][inty] && (inty-sy)*(ex-sx)==(ey-sy)*i)ret++;}}return ret;}int main (){while(scanf("%d%d%d",&n,&d,&m)!=EOF){if(n==0 && d==0 && m==0) break;memset(vis,0,sizeof(vis));memset(dp,0,sizeof(dp));n+=2*d;int tot=0;for(int i=1;i<=m;++i){int x,y,tt;scanf("%d%d%d",&x,&y,&tt);vis[tt][x+d][y+d]=1;tot=max(tot,tt);}for(int i=0;i<tot;++i) // from i to i+1{for(int x1=0;x1<n;++x1)for(int y1=0;y1<n;++y1){for(int x2=x1-d;x2<=x1+d;++x2)for(int y2=y1-d;y2<=y1+d;++y2)if(x2>=0 && x2<n && y2>=0 && y2<n && (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)<=d*d){int cnt=count(x1,y1,x2,y2,i+1);if(dp[i+1][x2][y2]<dp[i][x1][y1]+cnt)dp[i+1][x2][y2]=dp[i][x1][y1]+cnt;}}}int ans=0;for(int i=0;i<n;++i)for(int j=0;j<n;++j)ans=max(ans,dp[tot][i][j]);printf("%d\n",ans);}return 0;}