P2331 [SCOI2005]最大子矩阵

题目描述

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

输入格式

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

输出格式

只有一行为k个子矩阵分值之和最大为多少。

输入输出样例

输入 #1复制

  1. 3 2 2
  2. 1 -3
  3. 2 3
  4. -2 3
输出 #1复制

  1. 9
  2.  
  3. soldp[i][j][k]表示第一行匹配到i,第二行匹配到j,用了k个矩阵的最大值,XJB转移即可
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef int ll;
  4. inline ll read()
  5. {
  6. ll s=; bool f=; char ch=' ';
  7. while(!isdigit(ch)) {f|=(ch=='-'); ch=getchar();}
  8. while(isdigit(ch)) {s=(s<<)+(s<<)+(ch^); ch=getchar();}
  9. return (f)?(-s):(s);
  10. }
  11. #define R(x) x=read()
  12. inline void write(ll x)
  13. {
  14. if(x<) {putchar('-'); x=-x;}
  15. if(x<) {putchar(x+''); return;}
  16. write(x/); putchar((x%)+'');
  17. }
  18. #define W(x) write(x),putchar(' ')
  19. #define Wl(x) write(x),putchar('\n')
  20. const int N=,M=,inf=0x3f3f3f3f;
  21. int n,m,c,ans=-inf;
  22. int a[N][],S[][N],st[][N][];
  23. int dp[N][N][M];
  24. inline int cmin(int o,int a,int b)
  25. {
  26. return (S[o][a]<S[o][b])?a:b;
  27. }
  28. inline int ask(int o,int l,int r)
  29. {
  30. int oo=log2(r-l+);
  31. return cmin(o,st[o][l][oo],st[o][r-(<<oo)+][oo]);
  32. }
  33. inline void Solve()
  34. {
  35. int i,j,k;
  36. memset(dp,-,sizeof dp); dp[][][]=;
  37. for(i=;i<=n;i++)
  38. {
  39. for(j=;j<=c;j++)
  40. {
  41. for(k=;k<=i-;k++)
  42. {
  43. dp[i][][j]=max(dp[i][][j],dp[k][][j-]+S[][i]-S[][ask(,k,i-)]);
  44. dp[i][][j]=max(dp[i][][j],dp[k][][j]);
  45. }
  46. }
  47. }
  48. for(i=;i<=n;i++) ans=max(ans,dp[i][][c]);
  49. Wl(ans);
  50. }
  51. int main()
  52. {
  53. freopen("data.in","r",stdin);
  54. int i,j,k,l;
  55. R(n); R(m); R(c); S[][]=S[][]=S[][]=;
  56. for(i=;i<=n;i++)
  57. {
  58. S[m+][i]=S[m+][i-];
  59. for(j=;j<=m;j++)
  60. {
  61. S[j][i]=S[j][i-]+(a[i][j]=read());
  62. S[m+][i]+=a[i][j];
  63. }
  64. }
  65. for(k=;k<=m+;k++)
  66. {
  67. for(j=;j<=n;j++) st[k][j][]=j;
  68. for(i=;i<=;i++)
  69. {
  70. for(j=;j+(<<i)-<=n;j++) st[k][j][i]=cmin(k,st[k][j][i-],st[k][j+(<<(i-))][i-]);
  71. }
  72. }
  73. if(m==) {Solve(); return ;}
  74. // for(i=0;i<=n;i++) cout<<S[1][i]<<' '<<S[2][i]<<' '<<S[3][i]<<endl;
  75. // for(i=0;i<=n;i++) for(j=i;j<=n;j++)
  76. // {
  77. // cout<<i<<" "<<j<<":"<<S[1][ask(1,i,j)]<<" "<<S[2][ask(2,i,j)]<<" "<<S[3][ask(3,i,j)]<<endl;
  78. // }
  79. memset(dp,-,sizeof dp); dp[][][]=;
  80. for(i=;i<=n;i++) for(j=;j<=n;j++) for(k=;k<=c;k++)
  81. {
  82. if(i==&&j==) continue;
  83. for(l=;l<=i-;l++)
  84. {
  85. dp[i][j][k]=max(dp[i][j][k],dp[l][j][k-]+S[][i]-S[][ask(,l,i-)]);
  86. dp[i][j][k]=max(dp[i][j][k],dp[l][j][k]);
  87. }
  88. for(l=;l<=j-;l++)
  89. {
  90. dp[i][j][k]=max(dp[i][j][k],dp[i][l][k-]+S[][j]-S[][ask(,l,j-)]);
  91. dp[i][j][k]=max(dp[i][j][k],dp[i][l][k]);
  92. }
  93. if(i==j)
  94. for(l=;l<=i-;l++)
  95. {
  96. dp[i][j][k]=max(dp[i][j][k],dp[l][l][k-]+S[][i]-S[][ask(,l,i-)]);
  97. dp[i][j][k]=max(dp[i][j][k],dp[l][l][k]);
  98. }
  99. }
  100. // cout<<dp[1][1][1]<<' '<<dp[2][2][1]<<' '<<dp[2][2][2]<<' '<<dp[3][3][2]<<endl;
  101. for(i=;i<=n;i++) for(j=;j<=n;j++) ans=max(ans,dp[i][j][c]);
  102. Wl(ans);
  103. return ;
  104. }
  1.  

luogu2331的更多相关文章

  1. luogu2331 [SCOI2005]最大子矩阵

    题目大意 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠.1≤n≤100,1≤m≤2,1≤k≤10. 思路 #include < ...

  2. From 7.22 To 7.28

    From 7.22 To 7.28 大纲 竞赛 我们好像要跟队爷考试... 考试的时候做题吧 学科 还是跟之前一样吧, 完型和阅读几乎没做过... 运动 踢足球!!!!!! 可惜bb他们去上海了... ...

随机推荐

  1. Abp 领域事件简单实践 <二>

    上一篇说的是仓储增删改 的时候会自动触发领域事件. 其实也可以随时触发. 现在在应用层触发. 应用层依赖注入 EventBus public void Trigger() { var e = new ...

  2. C++标准库里自带的数值类型和字符串互相转换函数

    需要包含头文件 #include <string> 数值类型转成string类型: string to_string(int val); string to_string(unsigned ...

  3. VBA比较运算符

    VBA支持的比较运算符如下所示. 假设变量A=10,变量B=20,则 - 运算符 描述 示例 = 检查两个操作数的值是否相等.如果是,那么条件是真. (A = B)结果为:False <> ...

  4. Java后端HttpClient Post提交文件流 及服务端接收文件流

    客户端将文件转换为流发送: 依赖的包: <dependency> <groupId>org.apache.httpcomponents</groupId> < ...

  5. JS数组抽奖程序教学实例

    数组Javascript中非常重要的知识点,为了在课堂上提高学生兴趣,教学举例的选择就比较重要了. 为了提高学生兴趣,特设计一个可输入,可控制结束的,利用JS数组实现的抽奖教学实例.代码如下:

  6. APP漏洞之WebView File域同源策略绕过漏洞

    i春秋作家:MAX丶 基本知识Android架构 Kernel内核层 漏洞危害极大,通用性强 驱动由于多而杂,也可能存在不少漏洞 Libaries系统运行库层 系统中间件形式提供的运行库 包括libc ...

  7. RANSAC拟合算法

    最小二乘法只适合与误差较小的情况.试想一下这种情况,假使需要从一个噪音较大的数据集中提取模型(比方说只有20%的数据时符合模型的)时,最小二乘法就显得力不从心了. 算法简介 随机抽样一致算法(RANd ...

  8. leetcode-63. Unique Paths II · DP + vector

    题面 A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). ...

  9. linux——运维基础,与常用命令

    1 运维概述 1 什么是运维 服务器的运行维护 2 名词 IDC(互联网数据中心) 3 监控软件 zabbix(用的最多), nagios, cactti 4 常用的linux操作系统 1 CentO ...

  10. Flutter中的普通路由与命名路由(Navigator组件)

    Flutter 中的路由通俗的讲就是页面跳转.在 Flutter 中通过 Navigator 组件管理路由导航.并提供了管理堆栈的方法.如:Navigator.push 和 Navigator.pop ...