您的位置:首页 > 其它

[DP] bzoj1084: [SCOI2005]最大子矩阵

2018-01-02 14:01 465 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=1084

n*m的矩阵,选k个子矩阵,使得这个k个子矩阵分值之和最大。然后不能相互重叠。

数据范围m<=2,良心题

特判一下 然后乱DP一通就好

2018年以两道水题开场了

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int f[110][110][11];//f[第一列处理到第i个][第二列处理到第j个][矩阵个数k]
int a[110][11];
int s1[110],s2[110];
int main()
{
memset(f,128,sizeof(f));
memset(a,128,sizeof(a));
s1[0]=s2[0]=0;
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
if (m==1)
{
for (int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
s1[i]=s1[i-1]+x;
}
for (int i=0;i<=n;i++) a[i][0]=0;
for (int i=1;i<=n;i++)
{
for (int ki=1;ki<=k;ki++)
{
a[i][ki]=a[i-1][ki];
for (int j=0;j<i;j++)
{
a[i][ki]=max(a[j][ki-1]+s1[i]-s1[j],a[i][ki]);
}
}
}
printf("%d\n",a
[k]);
}
else
{
for (int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
s1[i]=s1[i-1]+x;
scanf("%d",&x);
s2[i]=s2[i-1]+x;
}
for (int i=0;i<=n;i++)
for (int j=0;j<=n;j++)
f[i][j][0]=0;
for (int i=1;i<=n;i++)//第一行
{
for (int j=1;j<=n;j++)//第二行
{
for (int ki=1;ki<=k;ki++)
{
f[i][j][ki]=max(f[i][j-1][ki],f[i-1][j][ki]); // 从上一个/左边一个 继承
for (int l=0;l<i;l++) f[i][j][ki]=max(f[i][j][ki],f[l][j][ki-1]+s1[i]-s1[l]); //从第一列选
for (int l=0;l<j;l++) f[i][j][ki]=max(f[i][j][ki],f[i][l][ki-1]+s2[j]-s2[l]); //从第二列选
if (i==j)//选一个k*2的矩阵
{
for (int l=0;l<i;l++) f[i][j][ki]=max(f[i][j][ki],f[l][l][ki-1]+s1[i]-s1[l]+s2[j]-s2[l]);
}
}
}
}
printf("%d\n",f

[k]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  bzoj dp