最小面积子矩阵

转自:https://blog.csdn.net/jaster_wisdom/article/details/52153685

题目描述

一个N*M的矩阵,找出这个矩阵中所有元素的和不小于K的面积最小的子矩阵(矩阵中元素个数为矩阵面积)

输入描述:

每个案例第一行三个正整数N,M<=100,表示矩阵大小,和一个整数K
接下来N行,每行M个数,表示矩阵每个元素的值

输出描述:

输出最小面积的值。如果出现任意矩阵的和都小于K,直接输出-1。
示例1

输入

复制
4 4 10
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16

输出

复制
1

#include <iostream>  
#include <cstring>  
using namespace std;  
  
int matrix[110][110];  
int num[110];  
int N,M;  
int K;  
  
void merge(int i,int j){  
    for(int p=0;p<N;p++){  
        for(int k=i;k<=j;k++){  
            num[p] += matrix[p][k];  //合并成一维数组   
        }  
    }  
}  
  
int findShortest(){  
    int start = 0,end = 0;  
    int sum = 0;  
    int len = N;  
    int ans = len + 1;   
    bool flag = false;  
    while(end < len){  
        if(sum < K){  
            sum += num[end];  
        }  
        while(sum >= K){  
            flag = true;  
            ans = min(ans,end-start+1);  
            sum -= num[start++];  
        }  
        end ++;  
    }  
    if(flag)  
        return ans;  
    else  
        return N*M;    //全部加起来值都没超过K   
}  
  
int main(){  
    while(cin>>N>>M){  
        cin>>K;  
        int sum = 0;  
        for(int i=0;i<N;i++){  
            for(int j=0;j<M;j++){  
                cin>>matrix[i][j];  
                sum += matrix[i][j];  
            }  
        }  
        if(sum < K)  
            cout<<-1<<endl;  
        else{  
            int min_element = N*M;  
            for(int i=0;i<M;i++){  
                for(int j=i;j<M;j++){  
                    memset(num,0,sizeof(num));  
                    merge(i,j);  
                    int temp = findShortest();  
                    temp = (j - i + 1) * temp;  
                    if(temp < min_element)  
                        min_element = temp;  
                }  
            }  
            cout<<min_element<<endl;  
        }     
    }  
    return 0;  
}  

//使用dp求解最小子序列。

转载于:https://www.cnblogs.com/BlueBlueSea/p/9229818.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值