题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1078
方法:由于该题目中是二维数组,并且每一个cell都可能被从几个方向探寻到,而不是一维的那样只会被从前往后的方向探寻到,所以,这里需要对这些cell(除起始点那个)根据里面含有的cheese量递增排序,然后根据这个顺序去考虑cell。可以这样理解,计算一个cell A作为当前递增非连续子序列最后一个元素时能获取多少的值,对于b,c ,d,e ....这些可以直接移动到a的cell,
首先要计算出b,c ,d,e。。这些cell作为递增非连续子序列最后一个元素时能获取多少的值,这是他们的最优解,然后根绝这些最优解计算出cell A作为当前递增非连续子序列最后一个元素时能获取多少的值的最优解。该题目的最优子结构是这样的,如果不按排序后的顺序处理的话,那么在计算出cell A作为当前递增非连续子序列最后一个元素时能获取多少的值的时候,很有可能其子问题(b,c ,d,e。。这些cell作为递增非连续子序列最后一个元素时能获取多少的值)还没有计算出,这样就不满足最优子结构
考虑一个cell作为当前递增非连续子序列最后一个元素的情况:从该cell开始,从4个方向水平或垂直的方向探寻值比该cell小的cell,看以这些cell作为递增非连续子序列最后一个元素时能获取多少chess,选择最大的一个和当前cell相加,得到当前cell作为当前递增非连续子序列最后一个元素时能获取多少的值,状态转移方程如下:
F(current_cell) =cerrent_cell.quantity +max({F(cell)| current_cell can be reached from cell in the scope of 4 directions});
最后结果,
Max({F(cell)|all the cells });
感谢:注意看清楚题目,题目要求老鼠移动的工程中不能转弯,要不就是水平要不就是垂直。
代码:
#include<iostream> #include<math.h> #include<algorithm> #include<queue> using namespace std; int const MAX =0x3f3f3f3f; struct Cell { int x,y; int quantity; }; struct matrixNode { int quantity; int sortIndex; int step; int x,y; }; bool cmp(Cell x,Cell y) { if(x.quantity<y.quantity) return true; return false; } bool canGo(int x,int y,int n) { return x>=1 && x<=n && y>=1 && y<=n; } int direction[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; int main() { int n, k; while(scanf("%d %d",&n,&k) && !(n==-1 && k==-1) ) { Cell cells[10002]; matrixNode matrix[101][101]; bool v[101][101]; int dp[10002]; memset(dp,0,sizeof(dp)); int c=1; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { cells[c].x=i; cells[c].y=j; scanf("%d",&cells[c].quantity); matrix[i][j].quantity = cells[c].quantity; c++; } sort(cells+2,cells+c,cmp); for(int i=2;i<=n*n;i++) matrix[cells[i].x][cells[i].y].sortIndex=i; matrix[1][1].sortIndex=1; cells[0].y = cells[0].x = cells[0].quantity =0; dp[1] = cells[1].quantity; for(int i=2;i<=n*n;i++) { int max = -MAX; for(int xx=1;xx<=k;xx++) for(int yy=0;yy<4;yy++) if(canGo(cells[i].x+direction[yy][0]*xx,cells[i].y+direction[yy][1]*xx,n) && matrix[cells[i].x+direction[yy][0]*xx][cells[i].y+direction[yy][1]*xx].quantity <cells[i].quantity ) max = max < dp[ matrix[cells[i].x+direction[yy][0]*xx][cells[i].y+direction[yy][1]*xx].sortIndex ] ? dp[ matrix[cells[i].x+direction[yy][0]*xx][cells[i].y+direction[yy][1]*xx].sortIndex ] :max; dp[i]=max+cells[i].quantity; } int max = -MAX; for(int i=1;i<=n*n;i++) max = max<dp[i] ? dp[i]:max; cout<<max<<endl; } return 0; }