BZOJ 1084: [SCOI2005]最大子矩阵【DP】
1084: [SCOI2005]最大子矩阵
Time Limit: 10 Sec Memory Limit: 162 MB
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
题解
这题很明显就是DP,虽然DFS也能做,但是这里主要讲DP的解法。
我们读题后会发现m只有1和2的情况,那么,分类讨论。
1.m=1
矩阵就退化成了一条线。
我们设f[k][i]表示从1~i中挑选k个连续字段的最优解,那么很容易想到在前面枚举一个j,从j+1~i为一个新的字段。
转移方程:f[k][i]=max(f[k][i],f[k−1][j]+sum[i]−sum[j])sum表示前缀和。
2.m=2
我们有了m=1的想法,那么m=2就好想了。
那么就再加上一维,f[k][i][j]表示第一列挑选到i,第二列挑选到j,共有k个矩阵的最优解。
在前面枚举个p。
转移方程:f[k][i][j]=max(f[k][i][j],f[k−1][p][j]+sum[i][1]−sum[p][1]);f[k][i][j]=max(f[k][i][j],f[k−1][i][p]+sum[j][2]−sum[p][2]);还有一种情况,就是当我们选的矩阵的宽等于2时,也就是i==j时
转移方程:f[k][i][j]=max(f[k][i][j],f[k−1][p][p]+mp[i][1]−mp[p][1]+mp[j][2]−mp[p][2]);
下面贴上代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,K,ans,mp[105][5],d[15][105],f[15][105][105];
int main(){scanf("%d%d%d",&n,&m,&K);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) scanf("%d",&mp[i][j]),mp[i][j]+=mp[i-1][j];if(m==1){for(int k=1;k<=K;k++)for(int i=1;i<=n;i++){d[k][i]=d[k][i-1];for(int j=0;j<i;j++) d[k][i]=max(d[k][i],d[k-1][j]+mp[i][1]-mp[j][1]);}ans=d[K][n];}else{for(int k=1;k<=K;k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){f[k][i][j]=max(f[k][i-1][j],f[k][i][j-1]);for(int p=0;p<i;p++) f[k][i][j]=max(f[k][i][j],f[k-1][p][j]+mp[i][1]-mp[p][1]);for(int p=0;p<j;p++) f[k][i][j]=max(f[k][i][j],f[k-1][i][p]+mp[j][2]-mp[p][2]);if(i==j)for(int p=0;p<j;p++) f[k][i][j]=max(f[k][i][j],f[k-1][p][p]+mp[i][1]-mp[p][1]+mp[j][2]-mp[p][2]);}ans=f[K][n][n];}printf("%d\n",ans);return 0;
}
转载于:https://www.cnblogs.com/XSamsara/p/9059460.html
BZOJ 1084: [SCOI2005]最大子矩阵【DP】相关推荐
- BZOJ 1084: [SCOI2005]最大子矩阵
1084 思路: dp[i][j][k]:第一列选前i个第二列选前j个总共选了k个子矩阵的最大值 注意空矩阵也算子矩阵 代码: #pragma GCC optimize(2) #pragma GCC ...
- [BZOJ] 1084 [SCOI2005]最大子矩阵
Time Limit: 10 Sec Memory Limit: 162 MB Submit: 3540 Solved: 1771 [Submit][Status][Discuss] Descript ...
- 1084. [SCOI2005]最大子矩阵【网格DP】
Description 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵 不能相互重叠. Input 第一行为n,m,k(1≤n≤100,1≤m≤ ...
- bzoj1084 [SCOI2005]最大子矩阵 dp
首先题目是要选几个连续的矩阵,有关连续类的问题是可以最优值直接在相邻两行转移的 而且题目中m<=2是非常方便的条件,分类讨论就可以了 注: 0 0也要转移 码: #include<iost ...
- P2331 [SCOI2005]最大子矩阵(DP分类讨论)
P2331 [SCOI2005]最大子矩阵(DP&分类讨论) 考虑dp解决. 若m=1m=1m=1则是一个简单的递推. 若m=2m=2m=2则是分情况讨论. 一个是当前行不取. 一个是选第一列 ...
- BZOJ 1087: [SCOI2005]互不侵犯King
二次联通门 : BZOJ 1087: [SCOI2005]互不侵犯King /*BZOJ 1087: [SCOI2005]互不侵犯King状压dp将每一行棋子的存在状态压成一个整数f[i][j][k] ...
- P2331 [SCOI2005]最大子矩阵 题解
DP 题,好像有点恶心,主要是因为能不能选空矩阵的问题. 有些数据好像是可以选空矩阵的有些又不能选,就很离谱,但是根据原数据来看空矩阵应该是不能选的,我也不知道具体情况() 注意到 m=1m=1m=1 ...
- [T][3]洛谷 P2331 [SCOI2005] 最大子矩阵
题目描述 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. 输入输出格式 输入格式: 第一行为n,m,k(1≤n≤100,1≤m≤2 ...
- 洛谷 P2331 [SCOI2005]最大子矩阵
PS:如果读过题了可以跳过题目描述直接到题解部分 提交链接:洛谷 P2331 [SCOI2005]最大子矩阵 题目 题目描述 这里有一个 n*m 的矩阵,请你选出其中 k 个子矩阵,使得这个 k 个子 ...
最新文章
- git根据用户过滤提交记录
- java url 本地文件是否存在_我的应用程序知道URL中是否存在文件会一直停止[重复]...
- Java中使用OpenSSL生成的RSA公私钥进行数据加解密
- strtof linux内核,Qt for Android使用grpc探索
- MINA,xSocket同样的性能缺陷及陷阱,Grizzly better
- 嵌入式系统开发之根文件系统
- linux卸载java rpm_详解Linux中查看jdk安装目录、Linux卸载jdk、rpm命令、rm命令参数...
- 【电脑使用】如何快速给PDF添加书签
- C#调用Excel Vba宏
- 1031 查验身份证 (15 分) python
- CEILING_2_POWER
- 关于win 右键菜单“新建” 项消失
- mmdetection目标检测训练过程参数解读
- 武汉大学计算机学院李明,第一届CSIG全国SLAM技术论坛成功举办
- 第19篇 基础(十九)详解QVector(数组)
- 【整理】X86常用的汇编指令及寄存器
- 微信小程序 —— 瀑布流简单写法(css3属性加wx:if判断轻松实现)
- 构建网络空间命运共同体 !麒麟信安参展2021年世界互联网大会“互联网之光”博览会
- python中generate什么意思_python中的list和generator
- 淘宝补单技巧,中小卖家须清楚的补单方法