BZOJ1084 最大子矩阵 [DP]

30 篇文章 0 订阅

1084: [SCOI2005]最大子矩阵

Time Limit: 10 Sec   Memory Limit: 162 MB
Submit: 3017   Solved: 1510
[ Submit][ Status][ Discuss]

Description

  这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵

不能相互重叠。

Input

  第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的

分值的绝对值不超过32767)。

Output

  只有一行为k个子矩阵分值之和最大为多少。

Sample Input


3 2 2

1 -3

2 3

-2 3

Sample Output


9

HINT

Source

思考

DP,利用前缀和的思想,预处理出前缀和。

因为m只能为1或2,分类讨论:
m=1时为k个普通的最大连续字段和:
f[i][j] 表示前i个数中取出j个矩形的最大和
转移:
f[i][j]=maxf[k][j1]+s[i]s[k1],f[k][j]
复杂度 O(n2K)
m=2时,设 f[i][j][k] 表示第一列选到第i个数,第二列选到第j个数时,总共k个子矩形的答案。利用背包DP选与不选的思想:
有①不做②选第一列③选第二列④i==j时选两列的情况。

f[i][j][k]=maxf[i1][j][k],f[i][j1][k],w[l][j][k1]+sum[i][1]sum[l1][1](l[1,i1]),f[i][r][k1]+sum[j][2]sum[r][2](r[1,j1]),f[l][r][k]+sum[i][1]+sum[i][2]sum[l][1]sum[l][2]

复杂度O(n^3*K)

#include<bits/stdc++.h>
#define REP(i,j) for(i=1;i<=j;i++)
#define RET(i,j) for(i=0;i<j;i++)
using namespace std;
int f[120][120][11],n,m,K,stf[120],sts[120];
inline void read(int &res){
    static char ch;int flag=1;
    while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;
    while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;
}
int main(){
    register int i,j,k,l;
    read(n),read(m);read(K);
    if(m==1){
        REP(i,n)read(k),stf[i]=stf[i-1]+k;
        REP(k,K)REP(i,n){
            f[n][i][k]=f[n][i-1][k];
            RET(j,i)f[n][i][k]=max(f[n][i][k],f[n][j][k-1]+stf[i]-stf[j]);
        }
    }else{
        REP(i,n)read(j),read(k),stf[i]=stf[i-1]+j,sts[i]=sts[i-1]+k;
        REP(k,K)REP(i,n)REP(j,n){
            f[i][j][k]=max(f[i-1][j][k],f[i][j-1][k]);
            RET(l,i)f[i][j][k]=max(f[i][j][k],f[l][j][k-1]+stf[i]-stf[l]);
            RET(l,j)f[i][j][k]=max(f[i][j][k],f[i][l][k-1]+sts[j]-sts[l]);
            if(i==j)RET(l,i)
                f[i][j][k]=max(f[i][j][k],f[l][l][k-1]+stf[i]-stf[l]+sts[j]-sts[l]);
        }
    }
    printf("%d",f[n][n][K]);
    return 0;
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值