题目是说有一家公司要挖金矿,但是资金有限,因此要合理选择一块矩形的矿地,金矿可以分割成1*1的小格,给出金矿的大小n*m,以及限制金额S。接下来是两个n*m的矩阵,第一个表示花费的金额,第二个表示收益。要求输出最大收益(注:选择的区域必须是矩形)
其实这个就跟dp里的最大子矩阵问题差不多,不过这里面没有负数,却多了一个花费金额来限制。
首先将每一行都压缩,也就是将前几项都加起来存到当前数组中,这样可以避免在后面重复计算前几项的和,而要单独用第i行第j项时,只需a[i][j]-=a[i][j-1]
for(i=1;i<=n;i++)
{ for(j=1;j<=m;j++) { if(j!=1) { a[i][j]+=a[i][j-1]; b[i][j]+=b[i][j-1]; } } }#include<stdio.h>#include<string.h>int
a[210][210],b[210][210],c[210][210];int
main(){ int T,n,m,i,j,t,k,xx,x,y,l; scanf("%d",&T); while(T--) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); scanf("%d%d%d",&n,&m,&l); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { scanf("%d",&a[i][j]); } } for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { scanf("%d",&b[i][j]); } } for(i=1;i<=n;i++)//压缩行
{ for(j=1;j<=m;j++) { if(j!=1) { a[i][j]+=a[i][j-1]; b[i][j]+=b[i][j-1]; } } } for(k=1;k<=m;k++)//从第k列开始
{ for(i=k;i<=m;i++)//从k往后的每一列
{ t=1;x=0;y=0; for(j=1;j<=n;j++)//对第i列每一行进行规划
{ x+=(a[j][i]-a[j][k-1]); //计算花费
if(x>l)//花费超出,则减去最上面的,直到不超
{ if(y>c[j-1][i])
c[j-1][i]=y; while(x>l) { x-=(a[t][i]-a[t][k-1]); y-=(b[t][i]-b[t][k-1]); t++; } y+=(b[j][i]-b[j][k-1]);//计算收益
} else y+=(b[j][i]-b[j][k-1]);
//否则,继续
} if(y>c[j-1][i])//到最下面,若收益比之前的多,则记录
c[j-1][i]=y; } } xx=0;//找到最大收益
for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { if(c[i][j]>xx)
xx=c[i][j]; } } printf("%d\n",xx); } return 0;}Coyouth 1583 问题 G: Enclosure Plan 解题报告,布布扣,bubuko.com
Coyouth 1583 问题 G: Enclosure Plan 解题报告
原文:http://www.cnblogs.com/qianshihuimou/p/3594877.html