这是本文档旧的修订版!
有横向运输和纵向运输的两种矿(要送到左端/上方),每个格子只能建一种方向(横/纵)的管道,最大化送到的矿的价值。
题解:想象一下对于每一格子来说如果它建横向那它左边必然都是横向才有意义,纵向同理。搞一下前缀和,状态转移
dp[i][j]=max(dp[i-1][j]+prea[i][j]-prea[i-1][j],dp[i][j-1]+preb[i][j]-preb[i][j-1])
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> using namespace std; int n,m,dp[505][505],prea[505][505],preb[505][505]; int main() { while(~scanf("%d%d",&n,&m)) { if(!n&&!m)return 0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%d",&prea[i][j]); prea[i][j]+=prea[i][j-1]+prea[i-1][j]-prea[i-1][j-1]; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%d",&preb[i][j]); preb[i][j]+=preb[i][j-1]+preb[i-1][j]-preb[i-1][j-1]; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { dp[i][j]=max(dp[i-1][j]+prea[i][j]-prea[i-1][j],dp[i][j-1]+preb[i][j]-preb[i][j-1]); } printf("%d\n",dp[n][m]); } return 0; }