标签:usaco 2008 open gold crisis on the farm 动态规划
题意:输入n、m、p然后是n头牛塔坐标、m个草垛坐标,有p次指令机会。
每次指令可以向上下左右其中一种方向,让所有牛塔都移动一单位。
然后每经过草垛/牛塔次,就有1个权值。
求权值最大值及使权值最大的移动指令序列(字典序最小)。
题解:f[i][j][k]表示第i次,移动序列x轴坐标为j,y轴k,最大权值。
然后倒着做以保证字典序。
代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 1010 #define M 32 #define inf 0x3f3f3f3f using namespace std; int n,m,p; int map[N][N]; int cx[N],cy[N]; int lx=inf,rx,ly=inf,ry; int f[M][M<<1][M<<1],ans; char opt[M][M<<1][M<<1]; int main() { // freopen("test.in","r",stdin); int i,j,k; int a,b,c; int x,y; scanf("%d%d%d",&n,&m,&p); for(i=1;i<=n;i++)scanf("%d%d",&cx[i],&cy[i]); for(i=1;i<=m;i++) { scanf("%d%d",&x,&y); map[x][y]=1; lx=min(lx,x),rx=max(rx,x); ly=min(ly,y),ry=max(ry,y); } for(i=p;i>=0;i--)// 走i步 { for(j=-i;j<=i;j++)// x轴位移 { int remain=i-abs(j); for(k=-remain;k<=remain;k++) { int noxus=-1,demacia=0; char tt; for(int adc=1;adc<=n;adc++) { x=cx[adc]+j,y=cy[adc]+k; if(lx<=x&&x<=rx&&ly<=y&&y<=ry&&map[x][y])demacia++; } if(f[i+1][j+1+M][k+M]>noxus)noxus=f[i+1][j+1+M][k+M],tt='E'; if(f[i+1][j+M][k+1+M]>noxus)noxus=f[i+1][j+M][k+1+M],tt='N'; if(f[i+1][j+M][k-1+M]>noxus)noxus=f[i+1][j+M][k-1+M],tt='S'; if(f[i+1][j-1+M][k+M]>noxus)noxus=f[i+1][j-1+M][k+M],tt='W'; f[i][j+M][k+M]=noxus+demacia; opt[i][j+M][k+M]=tt; } } } printf("%d\n",f[0][0+M][0+M]); x=y=0+M; for(i=0;i<p;i++) { printf("%c",opt[i][x][y]); if(opt[i][x][y]=='E')x++; else if(opt[i][x][y]=='W')x--; else if(opt[i][x][y]=='N')y++; else if(opt[i][x][y]=='S')y--; } return 0; }
【USACO 2008 Open Gold】 2.Crisis on the Farm 动规、
标签:usaco 2008 open gold crisis on the farm 动态规划
原文地址:http://blog.csdn.net/vmurder/article/details/42319491