欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解


题目传送门 - BZOJ1084


题意概括

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

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


题解

  注意到1<=m<=2!

  如果m = 1 ,那么就是一个简单的线性dp。

  我们设dp[i][j]表示在前i个里面选出k个子矩阵的最大分值。

  那么分两种情况讨论:

  1.  什么都不干: dp[i][j] = max(dp[i][j], dp[i-1][j])

  2. 弄一个新的子矩阵: dp[i][j] = max(dp[i][j], dp[x][j - 1] + presum[i] - presum[x])  0<=x<i

  时间复杂度O(kn2)

  如果 m = 2 ,那么是一个稍微复杂一点的线性dp。

  我们设dp[i][j][x]表示在第一列的前i个和第二列的前j个里面选出x个子矩阵的最大分值。

  那么分几种情况进行讨论:

  1. 什么都不干: dp[i][j][x] = max(dp[i][j][x], dp[i - 1][j][x], dp[i][j - 1][x])

  2. 在第一列弄一个新的子矩阵: dp[i][j][x] = max(dp[i][j][x], dp[y][j][x - 1] + presum[i][1] - presum[y][1])  0<=y<i

  3. 在第二列弄一个新的子矩阵: dp[i][j][x] = max(dp[i][j][x], dp[i][y][x - 1] + presum[j][2] - presum[y][2])  0<=y<j

  4. 在第一、二列弄一个宽度为2的子矩阵: dp[i][j][x] = max(dp[i][j][x], dp[y][y][x - 1] + presum[i][1] - presum[y][1] + presum[j][2] - presum[y][2])  i = j 且 0<=y<i

  时间复杂度O(kn3)


代码

  1. #include <cstring>
  2. #include <algorithm>
  3. #include <cstdlib>
  4. #include <cstdio>
  5. #include <cmath>
  6. using namespace std;
  7. const int N=+,M=,K=+;
  8. const int Inf=<<;
  9. int n,m,k,a[N][M];
  10. void solve1(){
  11. int dp[N][K],presum[N];
  12. for (int i=;i<N;i++)
  13. for (int j=;j<K;j++)
  14. dp[i][j]=-Inf;
  15. presum[]=;
  16. for (int i=;i<=n;i++)
  17. presum[i]=presum[i-]+a[i][];
  18. dp[][]=;
  19. int ans=-Inf;
  20. for (int i=;i<=n;i++)
  21. for (int j=;j<=k;j++){
  22. if (!i&&!j)
  23. continue;
  24. if (i)
  25. dp[i][j]=dp[i-][j];
  26. if (!j)
  27. continue;
  28. for (int x=;x<i;x++)
  29. dp[i][j]=max(dp[i][j],dp[x][j-]+presum[i]-presum[x]);
  30. }
  31. printf("%d",dp[n][k]);
  32. }
  33. void solve2(){
  34. int dp[N][N][K],presum[N][M];
  35. presum[][]=presum[][]=;
  36. for (int i=;i<=n;i++){
  37. presum[i][]=presum[i-][]+a[i][];
  38. presum[i][]=presum[i-][]+a[i][];
  39. }
  40. for (int i=;i<N;i++)
  41. for (int j=;j<N;j++)
  42. for (int x=;x<K;x++)
  43. dp[i][j][x]=-Inf;
  44. dp[][][]=;
  45. for (int i=;i<=n;i++)
  46. for (int j=;j<=n;j++)
  47. for (int x=;x<=k;x++){
  48. if (!i&&!j&&!x)
  49. continue;
  50. if (i&&j)
  51. dp[i][j][x]=max(dp[i-][j][x],dp[i][j-][x]);
  52. else if (i)
  53. dp[i][j][x]=dp[i-][j][x];
  54. else if (j)
  55. dp[i][j][x]=dp[i][j-][x];
  56. if (!x)
  57. continue;
  58. for (int y=;y<i;y++)
  59. dp[i][j][x]=max(dp[i][j][x],dp[y][j][x-]+presum[i][]-presum[y][]);
  60. for (int y=;y<j;y++)
  61. dp[i][j][x]=max(dp[i][j][x],dp[i][y][x-]+presum[j][]-presum[y][]);
  62. if (i==j)
  63. for (int y=;y<i;y++)
  64. dp[i][j][x]=max(dp[i][j][x],dp[y][y][x-]+presum[i][]-presum[y][]+presum[j][]-presum[y][]);
  65. }
  66. printf("%d",dp[n][n][k]);
  67. }
  68. int main(){
  69. scanf("%d%d%d",&n,&m,&k);
  70. for (int i=;i<=n;i++)
  71. for (int j=;j<=m;j++)
  72. scanf("%d",&a[i][j]);
  73. if (m==)
  74. solve1();
  75. else
  76. solve2();
  77. return ;
  78. }

BZOJ1084 [SCOI2005]最大子矩阵 动态规划的更多相关文章

  1. [bzoj1084][SCOI2005]最大子矩阵_动态规划_伪·轮廓线dp

    最大子矩阵 bzoj-1084 SCOI-2005 题目大意:给定一个n*m的矩阵,请你选出k个互不重叠的子矩阵使得它们的权值和最大. 注释:$1\le n \le 100$,$1\le m\le 2 ...

  2. bzoj千题计划198:bzoj1084: [SCOI2005]最大子矩阵

    http://www.lydsy.com/JudgeOnline/problem.php?id=1084 m=1: dp[i][j] 前i个数,选了j个矩阵的最大和 第i个不选:由dp[i-1][j] ...

  3. bzoj1084: [SCOI2005]最大子矩阵 dp

    这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. 题解:m很小分类讨论,m==1时怎么搞都可以,m==2时,dp[i][j][k]表 ...

  4. BZOJ 1084 [SCOI2005]最大子矩阵 - 动态规划

    传送门 题目大意: 从矩阵中取出k个互不重叠的子矩阵,求最大的和. 题目分析: 对于m=1,直接最大m子段和. 对于m=2: \(dp[i][j][k]\)表示扫描到第一列i和第2列j时选取了k个矩阵 ...

  5. bzoj1084: [SCOI2005]最大子矩阵

    dp.状态转移方程在代码里 #include<cstdio> #include<algorithm> #include<cstring> using namespa ...

  6. BZOJ1084 SCOI2005最大子矩阵

    考虑DP f[i][j][k]表示一行到i一行到j共取k块最大值,类似于最长公共子序列n^2那种 注意相等时可以一起拿 By:大奕哥 #include<bits/stdc++.h> usi ...

  7. [SCOI2005]最大子矩阵 (动态规划)

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

  8. bzoj1084 [SCOI2005]最大子矩阵——背包

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1084 水题...分类讨论一下即可. 代码如下: #include<iostream&g ...

  9. [bzoj1084][SCOI2005]最大子矩阵(DP)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1084 分析: m=1时:相当于只有一行数,让你取出p段,使得总和最大 明显可以DP,f ...

随机推荐

  1. luogu P3760 [TJOI2017]异或和

    传送门 对于每个二进制位考虑有多少区间和这一位上为1 从前往后扫每个前缀和,如果当前这个前缀和某一个二进制位上为1,因为区间和由这个前缀和减去前面的前缀和得来,如果减去了这一位为0的前缀和,那么 减去 ...

  2. python基础知识~配置文件模块

    一 配置文件模块   import ConfigParser ->导入模块  conf = ConfigParser.ConfigParser() ->初始化类二 系统函数  conf.r ...

  3. mysql 案例~关于pt-osc工具的用途

    简介:今天咱们聊聊PT-OSC的东东一 简单介绍  1 标准组合   pt-online-schema-change --user= --password= --host= D=,t= --sock= ...

  4. AJAX请求 $.ajaxSetup方法的使用:设置AJAX请求的默认参数选项,当程序中需要发起多个AJAX请求时,则不用再为每一个请求配置请求的参数

    定义和用法ajaxSetup() 方法为将来的 AJAX 请求设置默认值.语法$.ajaxSetup({name:value, name:value, ... }) 该参数为带有一个或多个名称/值对的 ...

  5. python渗透

    计划写一个获取qq空间加密相册的工具. 分析: 她的相册密码是手机号,先写一个生成手机号的脚本 空间有她之前的手机号,那么她现在的手机号也极有可能是一样的运营商,比如移动(缩小密码范围) 自己新建一个 ...

  6. ROS 错误之 [rospack] Error: package 'beginner_tutorials' not found

    ubuntu 下面情况处理 $ cd $gedit .bashrc 再后面加入两行 source /opt/ros/indigo/setup.bash source /home/lv/catkin_w ...

  7. SpringMVC集成MongoDb

    (1)pom添加相关依赖 <dependency> <groupId>org.springframework.data</groupId> <artifact ...

  8. Flex布局和Bootstrap布局两者的比较

    在Bootstrap中采用12栅格的布局,12份随意分配,但是不能解决5等分,7等分的问题.所以flex布局来协助. bootstrap的布局方式 <div class="row&qu ...

  9. tomcat jetty

    背景 其实这个比较毫无意义.只是当时突然知道了jetty,所以记下来,对于开发人员来说选择哪个一般意义不大. 转载 从架构上来看 Tomcat 在处理少数非常繁忙的连接上更有优势,也就是说连接的生命周 ...

  10. Android命令Monkey压力测试,详解

    一.Monkey 是什么?Monkey 就是SDK中附带的一个工具. 二.Monkey 测试的目的?:该工具用于进行压力测试. 然后开发人员结合monkey 打印的日志 和系统打印的日志,结局测试中出 ...