luogu2331
P2331 [SCOI2005]最大子矩阵
题目描述
这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵不能相互重叠。
输入格式
第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的分值的绝对值不超过32767)。
输出格式
只有一行为k个子矩阵分值之和最大为多少。
输入输出样例
3 2 2
1 -3
2 3
-2 3
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的更多相关文章
- luogu2331 [SCOI2005]最大子矩阵
题目大意 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠.1≤n≤100,1≤m≤2,1≤k≤10. 思路 #include < ...
- From 7.22 To 7.28
From 7.22 To 7.28 大纲 竞赛 我们好像要跟队爷考试... 考试的时候做题吧 学科 还是跟之前一样吧, 完型和阅读几乎没做过... 运动 踢足球!!!!!! 可惜bb他们去上海了... ...
随机推荐
- Linux自动运维工具Ansible的使用
Linux自动运维工具Ansible的使用 我们熟悉这个工具后, 可以很轻松的安装k8s. 一.介绍 ansible - run a task on a target host(s) Ansible是 ...
- (八)CXF之用spring添加拦截器
一.案例 本章案例是基于CXF之自定义拦截器基础之上改造的,目的是在服务端中用spring添加拦截器 配置web.xml <?xml version="1.0" encodi ...
- Mysql的实现原理
上篇文章已经简单介绍了Mysql索引的基本介绍,这篇文章主要讲解一下所以的实现原理.索引的定义其实非常复杂,严格的定义需要用到关系代数的概念,不在咱们讨论范围内,这里咱们只讨论mysql的常用的引擎的 ...
- 函数实现计算等差数列的第n项
等差数列的第n项 描述 等差数列是指从第二项起,每一项与它的前一项的差等于同一个常数的一种数列,这个常数叫做等差数列的公差. ...
- 3、Concurrenthashmap实现原理(JDK版本1.7)
(1)结构图: l ConcurrentHashMap中的数据结构 ConcurrentHashMap是由Segment数组结构和HashEntry数组结构组成.Segment实际继承自可重入锁(R ...
- html 输入框ios苹果手机显示九宫格数字键盘
只需要在input标签加上type=‘tel’ 即可
- ubuntu下使用libsvm
matlab上的代码已经八八九九了,因为涉及到GUI和网络编程的东西,所以不得已开始学python并在python上做完整版. 下面是如何在linux和python下使用libsvm 在你的pytho ...
- 【Linux】Linux基本命令
一.Linux关机 shutdown -h 10 10min后关机 shutdown -h 10:00 10:00关机 shutdown -h now 或 halt 或 poweroff 立即关机 ...
- Image Processing and Analysis_21_Scale Space:Feature Detection with Automatic Scale Selection——1998
此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...
- jade总结
随着时间的迁移,要跟官方api相匹配 jade的缺点 1.可移植性差 2.调试困难 3.性能不是非常出色(不是为性能设计,可以使用dot, http://olado.github.io/) 选择的 ...