P2331 [SCOI2005]最大子矩阵

题目描述

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

输入格式

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

输出格式

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

输入输出样例

输入 #1复制

3 2 2
1 -3
2 3
-2 3
输出 #1复制

9

sol:dp[i][j][k]表示第一行匹配到i,第二行匹配到j,用了k个矩阵的最大值,XJB转移即可
#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
ll s=; bool f=; char ch=' ';
while(!isdigit(ch)) {f|=(ch=='-'); ch=getchar();}
while(isdigit(ch)) {s=(s<<)+(s<<)+(ch^); ch=getchar();}
return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
if(x<) {putchar('-'); x=-x;}
if(x<) {putchar(x+''); return;}
write(x/); putchar((x%)+'');
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=,M=,inf=0x3f3f3f3f;
int n,m,c,ans=-inf;
int a[N][],S[][N],st[][N][];
int dp[N][N][M];
inline int cmin(int o,int a,int b)
{
return (S[o][a]<S[o][b])?a:b;
}
inline int ask(int o,int l,int r)
{
int oo=log2(r-l+);
return cmin(o,st[o][l][oo],st[o][r-(<<oo)+][oo]);
}
inline void Solve()
{
int i,j,k;
memset(dp,-,sizeof dp); dp[][][]=;
for(i=;i<=n;i++)
{
for(j=;j<=c;j++)
{
for(k=;k<=i-;k++)
{
dp[i][][j]=max(dp[i][][j],dp[k][][j-]+S[][i]-S[][ask(,k,i-)]);
dp[i][][j]=max(dp[i][][j],dp[k][][j]);
}
}
}
for(i=;i<=n;i++) ans=max(ans,dp[i][][c]);
Wl(ans);
}
int main()
{
freopen("data.in","r",stdin);
int i,j,k,l;
R(n); R(m); R(c); S[][]=S[][]=S[][]=;
for(i=;i<=n;i++)
{
S[m+][i]=S[m+][i-];
for(j=;j<=m;j++)
{
S[j][i]=S[j][i-]+(a[i][j]=read());
S[m+][i]+=a[i][j];
}
}
for(k=;k<=m+;k++)
{
for(j=;j<=n;j++) st[k][j][]=j;
for(i=;i<=;i++)
{
for(j=;j+(<<i)-<=n;j++) st[k][j][i]=cmin(k,st[k][j][i-],st[k][j+(<<(i-))][i-]);
}
}
if(m==) {Solve(); return ;}
// for(i=0;i<=n;i++) cout<<S[1][i]<<' '<<S[2][i]<<' '<<S[3][i]<<endl;
// for(i=0;i<=n;i++) for(j=i;j<=n;j++)
// {
// cout<<i<<" "<<j<<":"<<S[1][ask(1,i,j)]<<" "<<S[2][ask(2,i,j)]<<" "<<S[3][ask(3,i,j)]<<endl;
// }
memset(dp,-,sizeof dp); dp[][][]=;
for(i=;i<=n;i++) for(j=;j<=n;j++) for(k=;k<=c;k++)
{
if(i==&&j==) continue;
for(l=;l<=i-;l++)
{
dp[i][j][k]=max(dp[i][j][k],dp[l][j][k-]+S[][i]-S[][ask(,l,i-)]);
dp[i][j][k]=max(dp[i][j][k],dp[l][j][k]);
}
for(l=;l<=j-;l++)
{
dp[i][j][k]=max(dp[i][j][k],dp[i][l][k-]+S[][j]-S[][ask(,l,j-)]);
dp[i][j][k]=max(dp[i][j][k],dp[i][l][k]);
}
if(i==j)
for(l=;l<=i-;l++)
{
dp[i][j][k]=max(dp[i][j][k],dp[l][l][k-]+S[][i]-S[][ask(,l,i-)]);
dp[i][j][k]=max(dp[i][j][k],dp[l][l][k]);
}
}
// cout<<dp[1][1][1]<<' '<<dp[2][2][1]<<' '<<dp[2][2][2]<<' '<<dp[3][3][2]<<endl;
for(i=;i<=n;i++) for(j=;j<=n;j++) ans=max(ans,dp[i][j][c]);
Wl(ans);
return ;
}
 

luogu2331的更多相关文章

  1. luogu2331 [SCOI2005]最大子矩阵

    题目大意 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠.1≤n≤100,1≤m≤2,1≤k≤10. 思路 #include < ...

  2. From 7.22 To 7.28

    From 7.22 To 7.28 大纲 竞赛 我们好像要跟队爷考试... 考试的时候做题吧 学科 还是跟之前一样吧, 完型和阅读几乎没做过... 运动 踢足球!!!!!! 可惜bb他们去上海了... ...

随机推荐

  1. (十六)Hibernate中的延迟加载

    一.什么是延迟加载 为了节省Hibernate加载对象的性能节销,在Hibernate中真正需要用到这个对象时,才会发出        SQL语句来抓取这个对象.这一个过程称为延迟加载. 二.延迟加载 ...

  2. C#使用Selenium网页自动化

    工作中很多时候经常需要网抓数据或者把数据填写到网站上,使用Selenium将其自动化是一种不错的选择.Selenium其实是一个用于Web应用程序测试的工具,测试你的应用程序看是否能够很好地工作在不同 ...

  3. MVC的12种ActionResult介绍以及应用示例【转】

    一.介绍 1.ViewResult 表示一个视图结果,它根据视图模板产生应答内容.对应得Controller方法为View. 2.PartialViewResult 表示一个部分视图结果,与ViewR ...

  4. wince窗口被静态的焦点挡住

    效果如下图: 问题:文本框被挡住了 解决办法如下: 找到该窗体,设置属性Menu值为无即可解决

  5. 8.Redis的复制(Master/Slave)

    Redis的复制(Master/Slave) a)是什么 行话:也就是我们所说的主从复制,主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slave ...

  6. computed和watch的使用场景

    转载地址:https://blog.csdn.net/yuwenshi12/article/details/78561372 从作用机制和性质上看待methods,watch和computed的关系 ...

  7. linux修改文件系统注册设备

  8. 在 Queue 中 poll()和 remove()有什么区别?(未完成)

    在 Queue 中 poll()和 remove()有什么区别?(未完成)

  9. 《流畅的Python》Object References, Mutability, and Recycling--第8章

    Object References, Mutability, and Recycling 本章章节: Variables Are Not Boxes identity , Equality ,  Al ...

  10. 修改HTTPS加密协议TLS1.0为TLS1.2

    一:首先为什么要改为TLS1.2 因为各大浏览器相继发布声明将停止支持 TLS 1.0 和 TLS 1.1 https://www.cnblogs.com/jpush88/p/9846047.html ...