UVA - 10913 Walking on a Grid DAG路径最大值
2014-11-23 09:19
302 查看
题目大意:给出一个矩阵,要求求出从(1,1)走到(n,n)这个位置的路途上的数字的最大和,走的时候有限制,同一个位置不能走两次,有三个移动方向,下,左,右,还有一个限制,给出一个k,要求走过位置是负数的不能超过k
解题思路一:用一个四维数组来表示状态,dp[i][j][k][l]表示(i,j)位置,走了k个负数位置,移动方向是l
解法二:从上往下扫描,然后分别从左往右扫描每一行和从右往左扫描每一行,并进行比较,取最大值
解题思路一:用一个四维数组来表示状态,dp[i][j][k][l]表示(i,j)位置,走了k个负数位置,移动方向是l
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define LL long long #define maxn 80 #define MIN -((LL)1<<60) int N,K; int mov[3][2] = {{0,1},{1,0},{0,-1}}; bool vis[maxn][maxn][7][3],vis2[maxn][maxn]; long long dp[maxn][maxn][7][3],arr[maxn][maxn]; bool check(int x,int y) { return x >= 1 && x <= N && y >= 1 && y <= N; } long long solve(int x, int y, int z, int r) { bool &flag = vis[x][y][z][r]; long long &res = dp[x][y][z][r]; if(flag) return res; else if( (x == N && y == N) || z == 0) { flag = 1; if(z == 0) res = MIN; else res = arr[x][y]; return res; } else { res = MIN; for(int i = 0; i < 3; i++) { int xx = x + mov[i][0]; int yy = y + mov[i][1]; int t = 0; if(arr[x][y] < 0) t = - 1; if(check(xx,yy) && !vis2[xx][yy]) { if((r == 0 && i == 2) || (r == 2 && i == 0)) continue; vis2[xx][yy] = 1; long long temp = solve(xx,yy,z+t,i); if(temp != MIN) res = max(res,temp+arr[x][y]); vis2[xx][yy] = 0; } } flag = 1; return res; } } int main() { int mark = 1; while(scanf("%d%d",&N,&K) != EOF && N+K) { for(int i = 1; i <= N; i++) for(int j = 1; j <= N; j++) scanf("%lld", &arr[i][j]); if(arr < 0) K--; memset(vis,0,sizeof(vis)); memset(vis2,0,sizeof(vis2)); long long res = solve(1,1,K+1,1); if(res != MIN) printf("Case %d: %lld\n",mark++,res); else printf("Case %d: impossible\n",mark++); } return 0; }
解法二:从上往下扫描,然后分别从左往右扫描每一行和从右往左扫描每一行,并进行比较,取最大值
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define maxn 80 #define MIN -0x3f3f3f3f int N,k; int arr[maxn][maxn]; int dp[maxn][maxn][maxn],left[maxn][maxn],right[maxn][maxn]; void solve() { for(int i = 0 ; i <= k; i++) for(int j = 1; j <= N; j++) for(int l = 1; l <= N; l++) dp[i][j][l] = MIN; if(arr[1][1] >= 0) dp[0][1][1] = arr[1][1]; else dp[1][1][1] = arr[1][1]; for(int i = 0; i <= k; i++) for(int j = 1; j < N; j++) if(dp[i][1][j] != MIN) { if(arr[1][j+1] < 0) { if(dp[i][1][j] + arr[1][j + 1] > dp[i+1][1][j+1]) dp[i+1][1][j+1] = dp[i][1][j] + arr[1][j+1]; } else if (dp[i][1][j] + arr[1][j+1] > dp[i][1][j+1]) dp[i][1][j+1] = dp[i][1][j] + arr[1][j+1]; } for(int l = 2; l <= N; l++) { for(int i = 0; i <= k; i++) for(int j = 1; j <= N; j++) if(dp[i][l-1][j] != MIN) { if(arr[l][j] < 0) { if(dp[i][l-1][j] + arr[l][j] > dp[i+1][l][j]) dp[i+1][l][j] = dp[i][l-1][j] + arr[l][j]; } else if(dp[i][l-1][j] + arr[l][j] > dp[i][l][j]) dp[i][l][j] = dp[i][l-1][j] + arr[l][j]; } for(int i = 0; i <= k; i++) for(int j = 1; j <= N; j++) left[i][j] = right[i][j] = dp[i][l][j] ; for(int i = 0; i <= k; i++) for(int j = 1; j < N; j++) if(left[i][j] != MIN) { if(arr[l][j+1] < 0) { if(left[i][j] + arr[l][j+1] > left[i+1][j+1]) left[i+1][j+1] = left[i][j] + arr[l][j+1]; } else if (left[i][j] + arr[l][j+1] > left[i][j+1]) left[i][j+1] = left[i][j] + arr[l][j+1]; } for(int i = 0; i <= k; i++) for(int j = N; j > 1; j--) if(right[i][j] != MIN) { if(arr[l][j-1] < 0) { if(right[i][j] + arr[l][j-1] > right[i+1][j-1]) right[i+1][j-1] = right[i][j] + arr[l][j-1]; } else if (right[i][j] + arr[l][j-1] > right[i][j-1]) right[i][j-1] = right[i][j] + arr[l][j-1]; } for(int i = 0 ; i <= k; i++) for(int j = 1; j <= N; j++) dp[i][l][j] = left[i][j] > right[i][j] ? left[i][j] :right[i][j]; } } int main() { int mark = 1; while(scanf("%d%d",&N,&k) != EOF && N+k) { for(int i = 1; i <= N; i++) for(int j = 1; j <= N; j++) scanf("%d",&arr[i][j]); solve(); int max = MIN; for(int i = 0; i <= k; i++) if(dp[i] > max) max = dp[i] ; if(max != MIN) printf("Case %d: %d\n",mark++,max); else printf("Case %d: impossible\n",mark++); } return 0; }
相关文章推荐
- uva 1201 最小路径覆盖 最大匹配
- UVA 10048 Audiophobia 任意两点的路径上最大的边
- Uvalive 4267 Finding The Heaviest Path (Regionals 2008 Asia Taipei +DFS结点最大权值路径)
- 11.3.4-uva10048-floyd变形-两点之间路径上最大边的最小值
- UVA 10735 最大流 混合欧拉回路 输出路径
- UVA 10735 最大流 混合欧拉回路 输出路径
- Taxi Cab Scheme UVALive - 3126 最小路径覆盖解法(必须是DAG,有向无环图) = 结点数-最大匹配
- 算法练习笔记(八)—— 寻找最大路径树
- uva 437 (最大子序列和)
- UVA - 10131 Is Bigger Smarter?(dp+最大升序子序列)
- UVa 10246 Asterix and Obelix(变形的最短路径)
- UVAalive 3027 Corporative Network(并查集的路径压缩维护)
- UVA 11235 RMQ(范围最小值(最大值)问题):Sprase Table算法
- uva 1306 The K-League (最大流)
- 最大流,Floyd(UNIX插头 uva 753)
- poj 2594 Treasure Exploration(最小路径覆盖/二分最大匹配)
- UVA 1220 Party at Hali-Bula (树形dp--树的最大独立集)
- uva 11798 相对运动的最小最大距离
- UVa live3415Guardian of Decency(二分最大匹配之最大独立点集)
- UVa 1400 "Ray, Pass me the dishes!"(区间最大连续数组和)