题目传送

表示一开始也是一脸懵逼,虽然想到了DP,但面对多变的状态不知从何转移及怎么合理记录状态。之(借鉴大佬思路)后,豁然开朗,于是在AC后分享一下题解。

发现数据范围出奇地小,不过越是小的数据范围,算法的灵活性就越大。小数据对我们各个算法的组合及时间复杂度的掌握要求很高。面对二维的最优化选择,其实我们可以先通过搜索枚举出行的所有选择,存到一个数组team中,然后在行已经确认的情况下,跑一遍一维的DP:设dp[j][i]为在前j列选择i列的最优情况(为了方便,要求第i选择的列一定是第j列)。则状态转移方程就可写成:dp[j][i]=min(dp[j][i],dp[k][i-1]+lc[j]+hc[k][j]),其中lc为第j列的分值,hc[k][j]为第k列和第j列横向相邻元素对分值的贡献,k=i-1,i-1+1,...,j-1。对于lc和hk

我们可以在每次搜索完成后预处理一下,整个程序的时间复杂度即为O(C(n,r)*rm2),足以解出题。

代码上有一个小优化,详情见注释:

 #include <iostream>
#include <cstdio>
#include <cmath> using namespace std; int n, m, r, c, num[][], ans = 0x7fffffff, team[], lteam;
int lc[]; //列
int hc[][]; //列之间
int dp[][]; void init()
{
for (int i = ; i <= m; i++)
{
lc[i] = ;
for (int j = ; j < r; j++)
lc[i] += abs(num[team[j]][i] - num[team[j + ]][i]);
}
for (int i = ; i < m; i++)
for (int j = i + ; j <= m; j++)
{
hc[i][j] = ;
for (int k = ; k <= r; k++)
hc[i][j] += abs(num[team[k]][i] - num[team[k]][j]);
}
} void DP()
{
for (int i = ; i <= m; i++)
dp[i][] = lc[i];
if (c == )
{
for (int i = ; i <= m; i++)
ans = ans > dp[i][] ? dp[i][] : ans;
return;
}
for (int i = ; i <= c; i++)
{
for (int j = i; j <= m - c + i; j++)
{
dp[j][i] = 0x2fffffff;
for (int k = j - ; k >= i - ; k--)
dp[j][i] = min(dp[j][i], dp[k][i - ] + lc[j] + hc[k][j]);
}
}
for (int i = c; i <= m; i++)
ans = min(ans, dp[i][c]);
} void dfs(int now)
{
if (now > n)//选择完毕
{
init();
DP();
return;
}
if (r - lteam == n - now + )//当剩下的元素与还要选择的元素的数量相等时,必须要选
{
team[++lteam] = now;
dfs(now + );
--lteam;
return;
}
dfs(now + );//当前行要么不选
if (lteam < r)//要么在符合条件的情况下选
{
team[++lteam] = now;
dfs(now + );
--lteam;
}
} int main()
{
scanf("%d%d%d%d", &n, &m, &r, &c);
for (int i = ; i <= n; i++)
for (int j = ; j <= m; j++)
scanf("%d", &num[i][j]);
dfs();
printf("%d", ans);
return ;
}

洛谷P2258 子矩阵——题解的更多相关文章

  1. 洛谷P2258 子矩阵 题解 状态压缩/枚举/动态规划

    作者:zifeiy 标签:状态压缩.枚举.动态规划 题目链接:https://www.luogu.org/problem/P2258 这道题目状态压缩是肯定的,我们需要用二进制来枚举状态. 江湖上有一 ...

  2. 洛谷 P2258 子矩阵 解题报告

    P2258 子矩阵 题目描述 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取第 2 . 4行和第 ...

  3. 洛谷P2258 子矩阵

    P2258 子矩阵 题目描述 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取第2.4行和第2.4 ...

  4. 洛谷 P2258 子矩阵

    题目描述 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取第2.4行和第2.4.5列交叉位置的元素 ...

  5. 洛谷P2258 子矩阵[2017年5月计划 清北学堂51精英班Day1]

    题目描述 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取第2.4行和第2.4.5列交叉位置的元素 ...

  6. 洛谷NOIp热身赛题解

    洛谷NOIp热身赛题解 A 最大差值 简单树状数组,维护区间和.区间平方和,方差按照给的公式算就行了 #include<bits/stdc++.h> #define il inline # ...

  7. 洛谷P2827 蚯蚓 题解

    洛谷P2827 蚯蚓 题解 题目描述 本题中,我们将用符号 ⌊c⌋ 表示对 c 向下取整. 蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓. 蛐蛐国里现 ...

  8. 洛谷P1816 忠诚 题解

    洛谷P1816 忠诚 题解 题目描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意.但是由于一些人 ...

  9. [POI 2008&洛谷P3467]PLA-Postering 题解(单调栈)

    [POI 2008&洛谷P3467]PLA-Postering Description Byteburg市东边的建筑都是以旧结构形式建造的:建筑互相紧挨着,之间没有空间.它们共同形成了一条长长 ...

随机推荐

  1. js 如何定义函数

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  2. myBatis 基于javaBean配置

    MyBatis的持久化解决方案是将用户从原始的JDBC访问中解放出来,用户只需要定义需要操作的SQL语句, 无须关注底层的JDBC操作,就可以以面向对象的方式来进行持久化层操作.底层数据库连接的获取, ...

  3. python字符串-方法

    一.1. upper()作用:将字符串中字符转换为大写 In [17]: spam Out[17]: 'hello,world' In [18]: print(spam.upper()) HELLO, ...

  4. mybatis一级缓存和二级缓存的使用

    在mybatis中,有一级缓存和二级缓存的概念: 一级缓存:一级缓存 Mybatis的一级缓存是指SQLSession,一级缓存的作用域是SQLSession, Mabits默认开启一级缓存.在同一个 ...

  5. 2019 计蒜之道 初赛 第一场 商汤的AI伴游小精灵

    https://nanti.jisuanke.com/t/39260 根据题意我们可以知道  这是一个树 我们只需要找到出度最大的两个点就好了 如果包含根节点的话要-- 两个点相邻的话也要-- 数据很 ...

  6. PostgreSQL dblink使用过程

    安装: 进入/root/postgresql-11.2/contrib/dblink make && make install 切换到postgres用户 [root@fce40690 ...

  7. springboot swagger教程😀

    传送门开启:https://www.ibm.com/developerworks/cn/java/j-using-swagger-in-a-spring-boot-project/index.html

  8. JS之理解继承

    JS之理解继承:https://segmentfault.com/a/1190000010468293 1.call继承,也叫借用构造函数.伪造对象或是经典继承.call继承回把父类的私有属性和方法继 ...

  9. spring循环依赖是怎么解决的?

    回答:循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比如CircleA引用CircleB,CircleB引用CircleA,则它们最终反映为一个环. Spring如何解决循环依赖? ...

  10. mysql5.7单机多实例安装

    基于之前的mysql5.7单实例安装 修改/etc/my.cnf文件如下(这里配置4个实例,可自行修改数目) # # 多实例配置文件,可以mysqld_multi --example 查看例子 # [ ...