标签:处理 ref 返回 date none stream family 定义 png
小茗同学正在玩牧场物语。该游戏的地图可看成一个边长为n的正方形。
小茗同学突然心血来潮要去砍树,然而,斧头在小茗的右下方。
小茗是个讲究效率的人,所以他会以最短路程走到右下角,然后再返回到左上角。并且在路上都会捡到/踩到一些物品,比如说花朵,钱和大便等。
物品只能被取最多一次。位于某个格子时,如果格子上还有物品,就一定要取走。起点和终点上也可能有物品。
每种物品我们将为其定义一个价值,当然往返之后我们取得的物品的价值和越大越好。但是小茗同学正在认真地玩游戏,请你计算出最大的价值和。
多组数据(<=10),处理到EOF。
第一行输入正整数N(N≤100),表示正方形的大小。
接下来共N行,每行N个整数Ai,j(|Ai,j|≤10^9),表示相应对应位置上物品的价值。值为0表示没有物品。
每组数据输出一个整数,表示最大价值和。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 const int MAXN = 107; 8 typedef long long ll; 9 ll dp1[MAXN][MAXN], dp2[MAXN][MAXN]; 10 ll a[MAXN][MAXN], path[MAXN][MAXN]; 11 12 void update(int x, int y) 13 { 14 if (x <= 0 || y <= 0) return; 15 a[x][y] = 0; 16 if (path[x][y] == 0) { 17 update(x - 1, y); 18 } 19 else if (path[x][y] == 1) { 20 update(x, y - 1); 21 } 22 else return; 23 } 24 25 int main() 26 { 27 int N; 28 while (cin >> N) 29 { 30 for (int i = 1; i <= N; i++) 31 for (int j = 1; j <= N; j++) 32 cin >> a[i][j]; 33 memset(path, -1, sizeof(path)); 34 memset(dp1, 0, sizeof(dp1)); 35 memset(dp2, 0, sizeof(dp2)); 36 for (int i = 1; i <= N; i++) 37 for (int j = 1; j <= N; j++) 38 { 39 if (dp1[i - 1][j] > dp1[i][j - 1]) { 40 dp1[i][j] = a[i][j] + dp1[i - 1][j]; 41 path[i][j] = 0; 42 } 43 else 44 { 45 dp1[i][j] = a[i][j] + dp1[i][j - 1]; 46 path[i][j] = 1; 47 } 48 } 49 a[N][N] = 0; 50 a[1][1] = 0; 51 update(N, N); 52 for (int i = N; i >= 1; i--) 53 for (int j = N; j >= 1; j--) 54 dp2[i][j] = a[i][j] + max(dp2[i + 1][j], dp2[i][j + 1]); 55 cout << dp1[N][N] + dp2[1][1] << endl; 56 } 57 return 0; 58 }
或者,我想难道是这个方法有漏洞?
后来,我看了好多网上的博客,感觉大牛们的想法出奇的一致!:可以把问题转化成两个人同时走。两个人同时走?我一个人来回走就不行?????,谁让别人写的都是对的呢。。
思路就是用dp[k][x1][y1][x2][y2]表示俩人走第k步时的状态。空间复杂度高,易发现k+2=x+y,所以只记录k,x,优化掉y:dp[k][x1][x2],还不满意,感觉还高,由于本层状态只和上一层有关,所以用滚动数组,k只取0、1就好。dp[k][i][j]=max(dp[k^1][i][j],dp[k^1][i-1][[j-1],dp[k^1][i-1][j],dp[k^1][i][j-1])。(A下B下,A下B右,A右B下,A右B右四种情况转移)。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 typedef long long ll; 6 const ll INF=1e12; 7 const int MAXN=107; 8 ll dp[2][MAXN][MAXN]; 9 ll a[MAXN][MAXN]; 10 int N; 11 12 int main() 13 { 14 while(cin>>N)//多组数据多组数据!!!竟然还再这里WA 15 { 16 for(int i=0;i<=N;i++) 17 for(int j=0;j<=N;j++){ 18 dp[0][i][j]=dp[1][i][j]=-INF; 19 if(i>0&&j>0) 20 cin>>a[i][j]; 21 } 22 dp[0][1][1]=a[1][1]; 23 int c,k; 24 for(c=0,k=1;k<=2*N-2;k++) 25 { 26 c^=1; 27 for(int i=1;i<=N;i++) 28 for(int j=1;j<=N;j++){ 29 dp[c][i][j]=max(max(dp[c^1][i][j],dp[c^1][i-1][j-1]),max(dp[c^1][i-1][j],dp[c^1][i][j-1])); 30 if(i==j) 31 dp[c][i][j]+=a[i][k+2-i]; 32 else 33 dp[c][i][j]+=a[i][k+2-i]+a[j][k+2-j]; 34 } 35 } 36 cout<<dp[c][N][N]<<endl; 37 } 38 return 0; 39 }
标签:处理 ref 返回 date none stream family 定义 png
原文地址:http://www.cnblogs.com/zxhyxiao/p/7400280.html