POJ 1050 To the Max DP

题意:给定一个n*n的矩阵,求一个子矩阵,使得该矩阵的元素之和最大。

思路:经典的DP。由一维到二维。
1.必须先了解一维的情况,对于一维的数组而言,则转化为用DP求最大连续子序列,DP的状态方程为:sum[i] = max(sum[i-1] + num[i], 0)。
例如: num[]: -5, 7, -2, -6, 5, -1, 4
       sum[]:  0, 7, 5, 0, 5,  4,  8
2.对于二维的情况,则可转化为一维。将子矩阵的所有相同列的元素加在一起,问题就解决了。
例如: 若子矩阵为: -1, -2, -3,  5,  4
                   2, -5,  4,  7,  6
                   5,  5, -6, -2, -7
        变为: 6,  3, -5, 10, -3

#include < iostream >
using namespace std;

int maxSubArray ( int size, int array[] )
{
	int b = array[0];
	int i,max = array[0];
	for ( i = 1; i < size; i++ )
	{
		if ( b > 0 )
			b += array[i];
		else
			b = array[i];
		if ( b > max )
			max = b;
	}
	return max;
}

int maxSubMatri ( int x, int y, int array[][101] )
{
	int set[101];
	int i,j,k,temp,max = -130;
	for ( i = 0; i < x; i++ )
	{
		for ( k = 0; k < y; k++ )
			set[k] = 0;
		for ( j = i; j < x; j++ )
		{
			for ( k = 0; k < y; k++ )
				set[k] += array[j][k];
			temp = maxSubArray(y,set);
			if ( temp > max )
				max = temp;
		}
	}
	return max;
}

int main()
{
	int n,i,j;
	int array[101][101];
	cin >> n;
	for ( i = 0; i < n; i++ )
		for ( j = 0; j < n; j++ )
			cin >> array[i][j];
	cout << maxSubMatri(n,n,array) << endl;
	return 0;
}


#include <stdio.h> #include <stdlib.h> typedef int status; #define OK 1 #define ERROR 0 #define OVER_FLOW -2 #define TRUE 1 #define FALSE 0 #define LIST_INIT_SIZE 2 #define LIST_INCREASEMENT 2 #define N 6 typedef struct { int value; int quantity; int functionCount; } marbleType; typedef struct { marbleType *marble; int length; int listSize; } sqListMarble; typedef struct { status *state; int length; int listSize; } resultList; FILE *fp;// status initList_sq(sqListMarble *list); status initResultList(resultList *list); status sqListInsertM(sqListMarble *list,int quantity,int value); status insertResultList(resultList *list,status state); status calculate(int totalValue,sqListMarble *marbleList); int getCurMarbleValue(sqListMarble *marbleList,int marbleNumber); void printResult(resultList *list); main() { resultList result; int i,quantity,totalValue; sqListMarble marbleList; fp = fopen("data.txt","r");// initResultList(&result); while(1) { initList_sq(&marbleList); totalValue = 0; for(i = 0;i < N;i++) { fscanf(fp," %d",&quantity);// //scanf(" %d",&quantity); if(quantity) { sqListInsertM(&marbleList,quantity,i + 1); totalValue += quantity * (i + 1); } } if(!totalValue) break; insertResultList(&result,calculate(totalValue, &marbleList)); } printResult(&result); fclose(fp); } status initList_sq(sqListMarble *list) { list->marble = (marbleType *)calloc(LIST_INIT_SIZE,sizeof(marbleType)); if(!list->marble) exit(OVER_FLOW); list->length = 0; list->listSize = LIST_INIT_SIZE; return OK; } status sqListInsertM(sqListMarble *list,int quantity,int value) { marbleType *newBase; if(list->length >= list->listSize) { newBase = (marbleType *)realloc(list->marble,(list->listSize + LIST_INCREASEMENT) * sizeof(marbleType)); if(!newBase) exit(OVER_FLOW); list->marble = newBase; list->listSize += LIST_INCREASEMENT; } (list->marble + list->length)->quantity = quantity; (list->marble + list->length)->value = value; (list->marble + list->length)->functionCount = 0; list->length++; return OK; } status calculate(int totalValue,sqListMarble *marbleList) { int halfValue ,i,marbleNumber; int functionAmount = 1,value = 0; if(totalValue % 2) return FALSE; halfValue = totalValue / 2; for(i = 0; i < marbleList->length;i++) functionAmount *= (marbleList->marble + i)->quantity + 1; marbleList->marble->functionCount = -1; for(i = 0;i < functionAmount;i++) { value = 0; for(marbleNumber = 0;marbleNumber < marbleList->length;marbleNumber++) value += getCurMarbleValue(marbleList,marbleNumber); //putchar('\n');// if(value == halfValue) return TRUE; } return FALSE; } int getCurMarbleValue(sqListMarble *marbleList,int marbleNumber) { marbleType *marble = marbleList->marble + marbleNumber; if(marble == marbleList->marble) marble->functionCount++; if(marble->functionCount == marble->quantity + 1) { if(marbleList->marble + marbleList->length - 1 != marble ) (marble + 1)->functionCount++; marble->functionCount = 0; } //printf(" %d ",curCount);// return marble->functionCount * marble->value; } void printResult(resultList *list) { int i; for(i = 0;i < list->length;i++) { printf("Collection #%d:\n",i + 1); if(*(list->state + i) == 1) { printf("Can be divided.\n"); } else { printf("Can't be divided.\n"); } printf("\n"); } return; } status initResultList(resultList *list) { list->length = 0; list->listSize = LIST_INIT_SIZE; list->state = (status *)calloc(LIST_INIT_SIZE,sizeof(status)); if(!list->state) exit(OVER_FLOW); return OK; } status insertResultList(resultList *list,status state) { if(list->length >= list->listSize) { list->state = (status *)realloc(list->state,(list->listSize + LIST_INCREASEMENT) * sizeof(status)); if(!list->state) exit(OVER_FLOW); list->listSize += LIST_INCREASEMENT; } *(list->state + list->length) = state; list->length++; return OK; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值