您的位置:首页 > 其它

Codeforces Round #245 (Div. 1)B 递推DP

2014-08-29 18:36 281 查看
1000 * 1000的图,交点就一个,而且如何相交于一点 画一画就会发现就两种情况,所以首先想到的是可以暴力枚举交点,然后由交点往前推,相交过后两个人继续朝自己目的地前进,所以可以先 暴力枚举  并 递推出每一个点 到这个图的 四个顶点的 最大值,然后根据相交的两种情况取最优的一个即可

int mp[1000 + 55][1000 + 55];

int dp1[1000 + 55][1000 + 55],dp2[1000 + 55][1000 + 55],dp3[1000 + 55][1000 + 55],dp4[1000 + 55][1000 + 55];

int n,m;

void init() {
memset(mp,0,sizeof(mp));
memset(dp1,0,sizeof(dp1));
memset(dp2,0,sizeof(dp2));
memset(dp3,0,sizeof(dp3));
memset(dp4,0,sizeof(dp4));
}

bool input() {
while(cin>>n>>m) {
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&mp[i][j]);
return false;
}
return true;
}

void cal() {
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
dp1[i][j] = mp[i][j] + max(dp1[i - 1][j],dp1[i][j - 1]);//递推当前点到左边上边顶点大最大值
for(int i=1;i<=n;i++)
for(int j=m;j>0;j--)
dp2[i][j] = mp[i][j] + max(dp2[i - 1][j],dp2[i][j + 1]);//右边上边...
for(int i=n;i>0;i--)
for(int j=1;j<=m;j++)
dp3[i][j] = mp[i][j] + max(dp3[i + 1][j],dp3[i][j - 1]);//左边下边...
for(int i=n;i>0;i--)
for(int j=m;j>0;j--)
dp4[i][j] = mp[i][j] + max(dp4[i + 1][j],dp4[i][j + 1]);//右边下边...
int ans = 0;
/*暴力枚举交点,交点就一个*/
for(int i=2;i<n;i++) {/*不可能在第一列相遇,相遇后上下都被对方走过只能都向右走了就不行了,同理最后一列*/
for(int j=2;j<m;j++) {
ans = max(ans,dp1[i][j - 1] + dp2[i - 1][j] + dp3[i + 1][j] + dp4[i][j + 1]);//相交情况就两种,画画看就知道了
ans = max(ans,dp1[i - 1][j] + dp2[i][j + 1] + dp3[i][j - 1] + dp4[i + 1][j]);//注意当前交点的值不会被算进去
}
}
cout<<ans<<endl;
}

void output() {
}

int main () {
while(true) {
init();
if(input())return 0;
cal();
output();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: