http://acm.timus.ru/problem.aspx?space=1&num=1171
一天的时间,WA了N遍,居然是因为数组开小了呀,我勒个去!鄙视自己。。。。。。
我是从第 1 层往上更新的
dp[level][x][y][day] 表示到第level层的(x,y)位置(第level层已经用完,该去第level+1层)且用了 day 天时的最多食物量
d[level][x][y][x1][y1][day] 表示在第level层 从(x,y)到(x1,y1) 且用day天 最多获取事物量
d[level][x][y][x1][y1][day]的求取过程可以爆搜
dp[level][x][y][day]=max(dp[level][x][y][day] , dp[level-1][x1][y1][day1]+d1[level][x][y][x1][y1][day-day1])
代码:
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<vector> using namespace std; const double eps=1e-9; const int INF=0x3f3f3f3f; const int N=17; int dp[N][4][4][16*N]; int fx[N][4][4][16*N],fy[N][4][4][16*N],fd[N][4][4][16*N]; int d1[N][4][4][4][4][N]; int d[N][4][4][4][4][N]; int food[N][4][4]; int down[N][4][4]; int X[]={0,1,0,-1}; int Y[]={1,0,-1,0}; char dir[]={'E','S','W','N'}; bool visited[4][4]; int level,sx,sy; void dfs(int x,int y,int f,int ln,int path) { visited[x][y]=true; f+=food[level][x][y]; ++ln; if(d1[level][sx][sy][x][y][ln]<f) { d1[level][sx][sy][x][y][ln]=f; d[level][sx][sy][x][y][ln]=path; } for(int i=0;i<4;++i) { int x1=x+X[i]; int y1=y+Y[i]; if(x1>=0&&x1<4&&y1>=0&&y1<4&&!visited[x1][y1]) { int path1=(path|(i<<(2*(ln-1)))); dfs(x1,y1,f,ln,path1); } } visited[x][y]=false; } int main() { //freopen("data.in","r",stdin); int n,ex,ey; scanf("%d",&n); int days=n*16; for(int i=n;i>=1;--i) { for(int x=0;x<4;++x) for(int y=0;y<4;++y) scanf("%d",&food[i][x][y]); for(int x=0;x<4;++x) for(int y=0;y<4;++y) scanf("%d",&down[i][x][y]); } scanf("%d %d",&ex,&ey);--ex;--ey; for(int i=1;i<=n;++i) for(int x=0;x<4;++x) for(int y=0;y<4;++y) { for(int x1=0;x1<4;++x1) for(int y1=0;y1<4;++y1) for(int l=0;l<=days;++l) d1[i][x][y][x1][y1][l]=-1; memset(visited,false,sizeof(visited)); level=i;sx=x;sy=y; dfs(x,y,0,0,0); } memset(dp,-1,sizeof(dp)); for(int x=0;x<4;++x) for(int y=0;y<4;++y) dp[0][x][y][0]=0; for(int i=0;i<n;++i) for(int x=0;x<4;++x) for(int y=0;y<4;++y) for(int l=0;l<=days;++l) if(dp[i][x][y][l]>=0&&(down[i+1][x][y]||i==0)) { for(int x1=0;x1<4;++x1) for(int y1=0;y1<4;++y1) for(int r=1;r<=16;++r) if(d1[i+1][x1][y1][x][y][r]!=-1) { if(dp[i+1][x1][y1][l+r]<dp[i][x][y][l]+d1[i+1][x1][y1][x][y][r]) { add[i+1][x1][y1][l+r]=r; fx[i+1][x1][y1][l+r]=x; fy[i+1][x1][y1][l+r]=y; fd[i+1][x1][y1][l+r]=l; } } } int k=1; for(int l=1;l<=days;++l) if(dp[n][ex][ey][l]*k>dp[n][ex][ey][k]*l) k=l; printf("%.4f\n",1.0*dp[n][ex][ey][k]/k); vector<char>ans; int deep=n; while(deep>0) { int x1=fx[deep][ex][ey][k],y1=fy[deep][ex][ey][k],k1=fd[deep][ex][ey][k]; int path=d[deep][ex][ey][x1][y1][k-k1]; for(int i=1;i<k-k1;++i) { ans.push_back(dir[path&0x3]); path=path>>2; } ex=x1;ey=y1;k=k1; if(deep>1) {ans.push_back('D');} --deep; } printf("%d\n",ans.size()); for(unsigned int i=0;i<ans.size();++i) printf("%c",ans[i]); if(ans.size()>0) printf("\n"); return 0; }