洛谷P2331 [SCOI2005]最大子矩阵 DP
题意 :
这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵不能相互重叠。
第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的分值的绝对值不超过32767)。
思路:
注意这里的m只可能为1或者2.所以可以分开来考虑,对于m = 1,比较容易,dp[i][k] = dp[ t ][ k-1 ] + (t 到 i 的和)。然而对于m等于2的情况,我们可以开一个dp[ i ][ j ][ k ]. 表示第一行取前i个,第二行取前j个,取k个矩阵的最大值。那么就可以转移,当i!=j时,只可能是第一行的t推到 i 个,或者是第二行的t推到第 j 个,而当i == j时,还要考虑一个占两行的矩阵推移情况。
1)子矩阵可以为空矩阵。
2) 程序较大,容易写错下标,数组不要开小了。
#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <cassert> using namespace std;
#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue typedef long long ll;
typedef unsigned long long ull;
//typedef __int128 bll;
typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3; //priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl '\n' #define OKC ios::sync_with_stdio(false);cin.tie(0)
#define FT(A,B,C) for(int A=B;A <= C;++A) //用来压行
#define REP(i , j , k) for(int i = j ; i < k ; ++i)
#define max3(a,b,c) max(max(a,b), c);
#define min3(a,b,c) min(min(a,b), c);
//priority_queue<int ,vector<int>, greater<int> >que; const ll mos = 0x7FFFFFFF; //
const ll nmos = 0x80000000; //-2147483648
const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f; //
const int mod = 1e8+;
const double esp = 1e-;
const double PI=acos(-1.0);
const double PHI=0.61803399; //黄金分割点
const double tPHI=0.38196601; template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
} /*-----------------------showtime----------------------*/ const int maxn = ;
int mp[maxn][];
int dp[maxn][maxn][];
int s[][maxn];
int a[maxn][];
int main(){
int n,m,k;
scanf("%d%d%d", &n, &m, &k);
for(int i=; i<=n ;i++){
for(int j=; j<=m ; j++)
scanf("%d", &mp[i][j]);
} for(int i=; i<=m; i++){
for(int j=; j<=n; j++){
s[i][j] = s[i][j-] + mp[j][i];
}
} if(m == ){
int ans = ;
for(int i=; i<=n; i++){
for(int j=; j<=k; j++){
a[i][j] = a[i-][j];
for(int t=; t<i; t++)
{
a[i][j] = max(a[i][j], a[t][j-] + s[][i] - s[][t]);
}
ans = max(ans, a[i][j]);
}
}
printf("%d", ans );
}
else {
int ans = ;
for(int i=; i<=n; i++){
for(int j=; j<=n; j++){
for(int t = ; t <= k; t++){
dp[i][j][t] = max(dp[i-][j][t], dp[i][j-][t]);
for(int q = ; q < i; q ++)
dp[i][j][t] = max(dp[i][j][t], dp[q][j][t-] + s[][i] - s[][q]);
for(int q = ; q < j; q ++)
dp[i][j][t] = max(dp[i][j][t], dp[i][q][t-] + s[][j] - s[][q]); if(i==j){
for(int q=; q<i; q ++)
dp[i][j][t] = max(dp[i][j][t], dp[q][q][t-] + s[][i] + s[][i] - s[][q] - s[][q]);
}
ans = max(ans, dp[i][j][t]);
}
}
}
printf("%d\n", ans);
}
return ;
}
P2331
洛谷P2331 [SCOI2005]最大子矩阵 DP的更多相关文章
- 洛谷 P2331 [SCOI2005]最大子矩阵
洛谷 这一题,乍一眼看上去只想到了最暴力的暴力--大概\(n^4\)吧. 仔细看看数据范围,发现\(1 \leq m \leq 2\),这就好办了,分两类讨论. 我先打了\(m=1\)的情况,拿了30 ...
- 洛谷P2331 [SCOI2005] 最大子矩阵[序列DP]
题目描述 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. 输入输出格式 输入格式: 第一行为n,m,k(1≤n≤100,1≤m≤2 ...
- 洛谷P2331[SCOI2005]最大子矩阵
题目 DP 此题可以分为两个子问题. \(m\)等于\(1\): 原题目转化为求一行数列里的\(k\)块区间的和,区间可以为空的值. 直接定义状态\(dp[i][t]\)表示前i个数分为t块的最大值. ...
- BZOJ1084或洛谷2331 [SCOI2005]最大子矩阵
BZOJ原题链接 洛谷原题链接 注意该题的子矩阵可以是空矩阵,即可以不选,答案的下界为\(0\). 设\(f[i][j][k]\)表示前\(i\)行选择了\(j\)个子矩阵,选择的方式为\(k\)时的 ...
- bzoj1084&&洛谷2331[SCOI2005]最大子矩阵
题解: 分类讨论 当m=1的时候,很简单的dp,这里就不再复述了 当m=2的时候,设dp[i][j][k]表示有k个子矩阵,第一列有i个,第二列有j个 然后枚举一下当前子矩阵,状态转移 代码: #in ...
- 洛谷 P1896 [SCOI2005]互不侵犯
洛谷 P1896 [SCOI2005]互不侵犯 题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8 ...
- 洛谷 P5279 - [ZJOI2019]麻将(dp 套 dp)
洛谷题面传送门 一道 dp 套 dp 的 immortal tea 首先考虑如何判断一套牌是否已经胡牌了,考虑 \(dp\).我们考虑将所有牌按权值大小从大到小排成一列,那我们设 \(dp_ ...
- 【题解】洛谷P1896 [SCOI2005] 互不侵犯(状压DP)
洛谷P1896:https://www.luogu.org/problemnew/show/P1896 前言 这是一道状压DP的经典题 原来已经做过了 但是快要NOIP 复习一波 关于一些位运算的知识 ...
- BZOJ 1084: [SCOI2005]最大子矩阵 DP
1084: [SCOI2005]最大子矩阵 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1084 Description 这里有一个n* ...
随机推荐
- Linux系统管理----目录与文件管理作业习题
chapter02 - 03 作业 1. 分别用cat \tac\nl三个命令查看文件/etc/ssh/sshd_config文件中的内容,并用自己的话总计出这三个文档操作命令的不同之处? cat ...
- c语言指针汇总
1.指向单个变量的指针: ; int* p = &a; printf("%d", *p); 2.数组的指针 (1)一维数组的指针 ] = { ,,,, }; int *p; ...
- Thinkphp5.0快速入门笔记(2)
学习来源与说明 https://www.kancloud.cn/thinkphp/thinkphp5_quickstart 测试与部署均在windows10下进行学习. 示例建立新的模块和控制器 在a ...
- 闯荡Ext-第一篇
今天在网上找到了一本非常好的书:<Ext江湖>,这本书是由大漠穷秋大神写的,刚看到这本书的时候,心里面的那个激动劲啊,本来原先的时候心里面就一直念叨着想要学习Ext,但是苦于找不到好的资料 ...
- Docker笔记(七):常用服务安装——Nginx、MySql、Redis
开发中经常需要安装一些常用的服务软件,如Nginx.MySql.Redis等,如果按照普通的安装方法,一般都相对比较繁琐 —— 要经过下载软件或源码包,编译安装,配置,启动等步骤,使用 Docker ...
- centos开发环境安装
执行 yum install gcc gcc-c++ gcc-g77 flex bison autoconf automake bzip2-devel zlib-devel ncurses-devel ...
- sharding demo 读写分离 U (分库分表 & 不分库只分表)
application-sharding.yml sharding: jdbc: datasource: names: ds0,ds1,dsx,dsy ds0: type: com.zaxxer.hi ...
- java 购物商城小项目训练
java web 模拟购物车练习(项目一) 首页(index.jsp) <div align="center" class="index"> < ...
- 解决树莓派烧录系统后没有boot文件,只出现盘符问题
首先,如果下图情况,说明你没有烧录好,继续向下看 放一张安装成功的图片 出现这个的原因是因为前期没有烧录好,它会回滚到img文件中,如果中途退出,它会写入到img文件中 正确文件大小(Raspbian ...
- Promise对象的resolve回调函数和reject回调函数使用
Promise是ES6中用来结局回调地狱的问题的但是并不能帮我们减少代码量 Promise是一个构造函数 new Promise() 得到一个Promise一个实例 在Promise上有两个函数分别是 ...