SPOJ AMR11A Magic Grid(dp)

题目链接 http://www.spoj.com/problems/AMR11A/


题目大意:给出一个r * c大小的方格二维图,走到每个方格上需要加上上面的值,从左上角开始走,

规定只能往下右两个方向,要求全程值都大于零,求最开始最小值。


分析:倒着dp,开一个二维数组dp[r][c],dp[i][j]表示走到i, j位置所需最小值,可以得到初等关系:

           DP[I][J]+MAP[I][J]=DP[I+1][J]或者DP[I][J+1]

  移项,同时注意到每一步最小值为 1,可得:

            DP[I][J]=MAX{1,MIN { DP[I+1][J] , DP[I][J+1] } - MAP[I][J] };

(注意要分情况在边界的时候,以防越界)

代码如下


#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <ctype.h>
#include <cmath>
#include <stack>
#include <queue>
#include <sstream>
#include <set>
#include <map>
#include <vector>
#include <limits.h>
using namespace std;
typedef long long ll;
const int N = 500 + 10;
int grid[N][N];
int dp[N][N];

int r, c, t;

void DP(){
	dp[r][c] = 1;
	for(int i = r; i > 0; i--){
		for(int j = c; j > 0; j--){
			if(i == r && j == c){
				dp[i][j] = 1;
			}else if(i == r){
				dp[i][j] = max(1, dp[i][j+1] - grid[i][j]);
			}else if(j == c){
				dp[i][j] = max(1, dp[i+1][j] - grid[i][j]);
			}else{
				dp[i][j] = max(1, min(dp[i][j+1], dp[i+1][j]) - grid[i][j]);
			}
		}
	}
}

int main(){
	cin >> t;
	while(t--){
		cin >> r >> c;
		for(int i = 1; i <= r; i++){
			for(int j = 1; j <= c; j++){
				cin >> grid[i][j];
			}
		}
		DP();
		printf("%d\n", dp[1][1]);
	}
}

猜你喜欢

转载自blog.csdn.net/godjing007/article/details/80976945