北大ACM poj 1050

3 篇文章 0 订阅
1 篇文章 0 订阅

题意:给定一个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

              则now[]为: 6,  3, -5, 10, -3

 

源代码:(272K 16MS)

#include<iostream>
using namespace std;
const int Max = 105;

 

int max(int a, int b){
    return a > b ? a : b;
}

 

int main(){
    int n, i, j, k, row, col, sum, ans;
    int num[Max][Max], now[Max];
    cin >> n;
    row = col = n;
    for(i = 0; i < row; i ++)
        for(j = 0; j < col; j ++)
            cin >> num[i][j];

    ans = sum = 0;
    for(i = 0; i < row; i ++){
        memset(now, 0, sizeof(now));
        for(j = i; j < row; j ++)    //  求第i行到第j行的子矩阵。
            for(k = 0, sum = 0; k < col; k ++){ 
                now[k] += num[j][k];
                sum = max(sum + now[k], 0);
                if(sum > ans) ans = sum;
            }
    }
    cout << ans << endl;
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值