hdu1081dp

思路:这题就是将一维最大字段和,扩展到了二维;

一维的算法是这样的

int max_sum(int n)
{
    int i, j, sum = 0, max = -10000;
    for(i = 1; i <= n; i++)
    {
        if(sum < 0)
            sum = 0;
        sum += a[i];
        if(sum > max)
            max = sum;
    }
    return sum;
}
扩展到二维的时候也是同样的方法,不过需要将二维压缩成一维,所以我们要将数据做一下处理,使得map[i][j]从表示第i行第j个元素变成表示第i行前j个元素和,这样map[k][j]-map[k][i]就可以表示第k行从i->j列的元素和。只要比一维多两层循环枚举i和j就行了。

/*****************************************
Author      :Crazy_AC(JamesQi)
Time        :2015
File Name   :
*****************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <limits.h>
using namespace std;
#define MEM(a,b) memset(a,b,sizeof a)
#define pk push_back
template<class T> inline T Get_Max(const T&a,const T&b){return a < b?b:a;}
template<class T> inline T Get_Min(const T&a,const T&b){return a < b?a:b;}
typedef long long ll;
typedef pair<int,int> ii;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int maxn = 110;
int gg[maxn][maxn];
int n;
int main()
{	
	// ios::sync_with_stdio(false);
	// freopen("in.txt","r",stdin);
	// freopen("out.txt","w",stdout);
	while(~scanf("%d",&n)){
		MEM(gg, 0);
		int buf;
		for (int i = 1;i <= n;++i) {
			for (int j = 1;j <= n;++j){
				scanf("%d",&buf);
				gg[i][j] += gg[i][j - 1] + buf;
			}
		}
		int Max_Num = -INF;
		for (int i = 1;i <= n;++i){
			for (int j = i;j <= n;++j){
				int sum = 0;
				for (int k = 1;k <= n;++k){
					if (sum < 0)
						sum = 0;
					sum += gg[k][j] - gg[k][i - 1];
					if (sum > Max_Num) Max_Num = sum;
				}
			}
		}
		printf("%d\n",Max_Num);
	}
	return 0;
}


你可能感兴趣的:(dp)