洛谷

这一题,乍一眼看上去只想到了最暴力的暴力——大概\(n^4\)吧。

仔细看看数据范围,发现\(1 \leq m \leq 2\),这就好办了,分两类讨论。

我先打了\(m=1\)的情况,拿了30分。

就相当于最大\(k\)段子段和。

直接用\(dp[i][j][0/1]\)数组表示第\(i\)个选了\(j\)段的最大值,0代表不选,1为选。

那么状态转移方程也很简单:

  • \(dp[i][j][1]=max(dp[i-1][j-1][0],dp[i-1][j][1])+t[i];\)
  • \(dp[i][j][0]=max(dp[i-1][j][0],dp[i-1][j][1]);\)

而\(m=2\)的情况怎么弄呢?

实际上设计好状态,状态转移方程就出来了。

设\(f[i][j][0,1,2,3,4]\)表示第\(i\)行选\(j\)个矩阵的最大值。

  • \(f[i][j][0]\)表示不选第\(i\)行。
  • \(f[i][j][1]\)表示选第\(i\)行的左边一段。
  • \(f[i][j][2]\)表示选第\(i\)行的右边一段。
  • \(f[i][j][3]\)表示选第\(i\)行左边和右边,分别代表两个段。
  • \(f[i][j][4]\)表示选第\(i\)行左右两边,只代表一段。

那么状态转移方程也很好出来了。

  • \(f[i][j][0]=max\{f[i-1][j][0],f[i-1][j][1],f[i-1][j][2],f[i-1][j][3],f[i-1][j][4]\};\)

  • \(f[i][j][1]=max\{f[i-1][j-1][0],f[i-1][j][1],f[i-1][j-1][2],f[i-1][j][3], f[i-1][j-1][4]\}+a[i][0];\)

  • \(f[i][j][2]=max\{f[i-1][j-1][0],f[i-1][j-1][1],f[i-1][j][2],f[i-1][j][3], f[i-1][j-1][4]\}+a[i][1];\)

  • \(f[i][j][4]=max\{f[i-1][j-1][1],f[i-1][j-1][2],f[i-1][j][3]\}+a[i][0]+a[i][1];\)

  • \(if~(j>=2)~f[i][j][3]=max\{f[i][j][3],f[i-1][j-2][4]+a[i][0]+a[i][1]\};\)

  • \(f[i][j][4]=max\{f[i-1][j-1][0],f[i-1][j-1][1],f[i-1][j-1][2],f[i-1][j-1][3],f[i-1][j][4]\}+a[i][0]+a[i][1];\)

那么状态转移方程出来了就上代码吧!

那么多\(max\)连在一起真是美如画呀~

#include <bits/stdc++.h>
#define N 101
#define K 11
using namespace std;
int n,m,k;
const int mx=0x3f3f3f3f; int dp[N][K][2],t[N];
void work1()
{
for (int i=1;i<=n;++i) cin>>t[i];
for (int i=1;i<=n;++i)
for (int j=1;j<=k;++j) {
dp[i][j][1]=max(dp[i-1][j][1],dp[i-1][j-1][0])+t[i];
dp[i][j][0]=max(dp[i-1][j][0],dp[i-1][j][1]);
}
cout<<max(dp[n][k][0],dp[n][k][1]);
} int f[N][K][5],a[N][2];
void work2()
{
memset(f,-mx,sizeof(f));
for (int i=0;i<=n;i++)
for (int j=0;j<=k;j++) f[i][j][0]=0;
for (int i=1;i<=n;++i) cin>>a[i][0]>>a[i][1];
for (int i=1;i<=n;++i)
for (int j=1;j<=k;++j) {
f[i][j][0]=max(f[i-1][j][0],max(f[i-1][j][1],max(f[i-1][j][2],max(f[i-1][j][3],f[i-1][j][4]))));
f[i][j][1]=max(f[i-1][j-1][0],max(f[i-1][j][1],max(f[i-1][j-1][2],max(f[i-1][j][3],f[i-1][j-1][4]))))+a[i][0];
f[i][j][2]=max(f[i-1][j-1][0],max(f[i-1][j-1][1],max(f[i-1][j][2],max(f[i-1][j][3],f[i-1][j-1][4]))))+a[i][1];
f[i][j][3]=max(f[i-1][j-1][1],max(f[i-1][j-1][2],f[i-1][j][3]))+a[i][0]+a[i][1];
if (j>1) f[i][j][3]=max(f[i][j][3],f[i-1][j-2][4]+a[i][0]+a[i][1]);
f[i][j][4]=max(f[i-1][j-1][0],max(f[i-1][j-1][1],max(f[i-1][j-1][2],max(f[i-1][j-1][3],f[i-1][j][4]))))+a[i][0]+a[i][1];
}
cout<<max(f[n][k][0],max(f[n][k][1],max(f[n][k][2],max(f[n][k][3],f[n][k][4]))));
} int main()
{
cin>>n>>m>>k;m!=2?work1():work2();
return 0;
}

洛谷 P2331 [SCOI2005]最大子矩阵的更多相关文章

  1. 洛谷P2331 [SCOI2005]最大子矩阵 DP

    P2331 [SCOI2005]最大子矩阵 题意 : 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. 第一行为n,m,k(1≤n≤ ...

  2. 洛谷P2331 [SCOI2005] 最大子矩阵[序列DP]

    题目描述 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. 输入输出格式 输入格式: 第一行为n,m,k(1≤n≤100,1≤m≤2 ...

  3. 洛谷P2331[SCOI2005]最大子矩阵

    题目 DP 此题可以分为两个子问题. \(m\)等于\(1\): 原题目转化为求一行数列里的\(k\)块区间的和,区间可以为空的值. 直接定义状态\(dp[i][t]\)表示前i个数分为t块的最大值. ...

  4. BZOJ1084或洛谷2331 [SCOI2005]最大子矩阵

    BZOJ原题链接 洛谷原题链接 注意该题的子矩阵可以是空矩阵,即可以不选,答案的下界为\(0\). 设\(f[i][j][k]\)表示前\(i\)行选择了\(j\)个子矩阵,选择的方式为\(k\)时的 ...

  5. bzoj1084&&洛谷2331[SCOI2005]最大子矩阵

    题解: 分类讨论 当m=1的时候,很简单的dp,这里就不再复述了 当m=2的时候,设dp[i][j][k]表示有k个子矩阵,第一列有i个,第二列有j个 然后枚举一下当前子矩阵,状态转移 代码: #in ...

  6. 洛谷 P1896 [SCOI2005]互不侵犯

    洛谷 P1896 [SCOI2005]互不侵犯 题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8 ...

  7. BZOJ1088或洛谷2327 [SCOI2005]扫雷

    BZOJ原题链接 洛谷原题链接 很容易发现答案就只有\(0,1,2\)三种答案,而且只要知道第一个格子是否有雷就可以直接顺推下去了. 所以我们跑一次首位有雷,跑一次首位无雷判断是否可行即可. #inc ...

  8. 【题解】洛谷P1896 [SCOI2005] 互不侵犯(状压DP)

    洛谷P1896:https://www.luogu.org/problemnew/show/P1896 前言 这是一道状压DP的经典题 原来已经做过了 但是快要NOIP 复习一波 关于一些位运算的知识 ...

  9. 洛谷 P2331 最大子矩阵 题解

    题面 对于m==1和m==2两种状态进行不同的dp: 设sum[i][1]表示第一列的前缀和,sum[i][2]表示第二列的前缀和: sum[i][1]=sum[i-1][1]+a[i][1]; su ...

随机推荐

  1. Java中数据库连接的一些方法资料汇总

    Java中Connection方法笔记 http://www.cnblogs.com/bincoding/p/6554954.html ResultSet详解(转)  https://www.cnbl ...

  2. 使用jquery dialog

    网页开发中,弹窗还是很有必要的.本人比较喜欢jquery ui的dialog. 但是jquery dialog中也有一些略显不方便的,如:没有z-index的参数设置,脚部的按钮样式没办法自定义…… ...

  3. curl编译

    首先下载并解压: wget http://curl.haxx.se/download/curl-7.37.1.tar.gz tar -xzvf curl-7.37.1.tar.gz 编译安装: cd ...

  4. POJ 2472 106 miles to Chicago

    最短路问题变形. 题意是给你一些道路,和路过时不被抓的概率. 要求找一条到达目的地时不被抓的最大概率概率. 初始 dis[]设为 1 .其余为 0 .找最大就可以. #include<cstdi ...

  5. linux控制台超时自动注销

    仅让root用户超时退出: 编辑/root/.bash_profile文件,添加 export TMOUT=300 #300秒超时自动退出root 对所有用户设置自动注销: vi /etc/profi ...

  6. pipe_wait问题_转

    转自:调用Process.waitfor导致的进程挂起 最近遇到pipe_wait问题,父进程调用子进程时,子进程阻塞,cat /proc/$child/wchan输出pipe_wait,进程阻塞在p ...

  7. php判断今日是本月的第几个星期几

    php判断今日是本月的第几个星期几 php中有一个非常强悍的系统函数date()函数.巧妙的利用他可以实现显示任意我们需要的时间.比如今天遇到个需要是要判断今天是本月的第几个星期几,这里就不讨论这种说 ...

  8. EasyUI简单CRUD

    <!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head>    < ...

  9. php检测非法字符方法

    检测非法字符: [第一种]: 自己搞来玩的... 简单测试了下...暂无发现什么问题...日后再多测试下....日后再更>>>

  10. 设计模式之简单工厂模式(Simply Factory)摘录

    从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫静态工厂方法(Static Factory Method)模式.但不属于23种GOF设计模式之中的一个.简单工厂模式是由一个工厂对象决定创建出 ...