Martian Mining poj2948

来源:互联网 发布:仿58同城源码 php 编辑:程序博客网 时间:2024/05/22 00:33

这题要注意决策的转移,对每一行来说,选一个点作为基准点k,基准点左边(j < k)的点全部向左运输,基准点向右(j >= k)全部向上运输,不难想到其他的决策都不可能得到更优解,

而够转移到该状态的上一行状态的基准点一定是(j >= k),如果上一行基准点j<k的话则 j<= i < k的矿是无法向上运输的


#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <queue>#include <algorithm>#include <vector>#include <cstring>#include <stack>#include <cctype>#include <utility>   #include <map>#include <string>  #include <climits> #include <set>#include <string> #include <sstream>#include <utility>#include <ctime> using std::priority_queue;using std::vector;using std::swap;using std::stack;using std::sort;using std::max;using std::min;using std::pair;using std::map;using std::string;using std::cin;using std::cout;using std::set;using std::queue;using std::string;using std::istringstream;using std::make_pair;using std::greater;using std::endl;const int MAXN(510);int table[MAXN], mx[MAXN];int A[MAXN][MAXN], B[MAXN][MAXN];int main(){int n, m;while(scanf("%d%d", &n, &m), n || m){for(int i = 1; i <= n; ++i)for(int j = 1; j <= m; ++j)scanf("%d", A[i]+j);for(int i = 1; i <= n; ++i)for(int j = 1; j <= m; ++j)scanf("%d", B[i]+j);memset(mx, 0, sizeof(mx));for(int i = n; i >= 1; --i){int suma = 0, sumb = 0;for(int j = 1; j <= m; ++j)sumb += B[i][j];for(int j = 1; j <= m+1; ++j){table[j] = mx[j]+suma+sumb;suma += A[i][j];sumb -= B[i][j];}mx[m+1] = table[m+1];for(int j = m; j >= 1; --j)mx[j] = max(table[j], mx[j+1]);}int ans = 0;for(int i = 1; i <= m+1; ++i)ans = max(ans, table[i]);printf("%d\n", ans);}return 0;}