【洛谷】P1006 传纸条
0.总结
Get to the points first. The article comes from LawsonAbs!
- 坐标上的dp题
1.题意
这题和P1004 方格取数 很像。
2.分析
题中有坐标的dp题都是有明显提示的,那么这题也是一样,很容易就能找到状态转移方程。
令dp[i][x1][x2]表示的是一共走了i步,然后坐标点在(x1,i+2-y1),(x2,i+2-y2)时所能取到的最大值。 如果二者的横坐标相同,则需要减去重复加的值。
3.代码
#include<iostream>
using namespace std;
const int N = 105;//路径成2倍
int n,m;
int dp[N][N][N],arr[N][N];
int main(){
cin >> m >> n;
for(int i = 1;i<= m;i++){
for(int j = 1;j<= n;j++){
cin >> arr[i][j];
}
}
dp[0][1][1] = arr[1][1];//初始化
int y1,y2;
for(int i = 1;i <= n+m-2; i++){//走得步数 [0,n+m-2]
for(int x1 = 1; x1 <= m; x1++){
for(int x2 = 1; x2<= m; x2++){
y1= i+2-x1; y2=i+2-x2;
int temp = arr[x1][y1] + arr[x2][y2];
//向右,向右
dp[i][x1][x2] = max(dp[i][x1][x2], dp[i-1][x1][x2] + temp);
//向下,向右
dp[i][x1][x2] = max(dp[i][x1][x2], dp[i-1][x1-1][x2] + temp);
//向下,向下
dp[i][x1][x2] = max(dp[i][x1][x2], dp[i-1][x1-1][x2-1] + temp) ;
//向右,向下
dp[i][x1][x2] = max(dp[i][x1][x2], dp[i-1][x1][x2-1] + temp) ;
if(x1 == x2)//存在重复的情况
dp[i][x1][x2] -= arr[x1][y1];
}
}
}
cout << dp[n+m-2][m][m]<<"\n";
}
测试用例
3 3
0 0 0
0 0 0
0 1 0
3 3
0 3 9
2 8 5
5 7 0