【洛谷P2258】子矩阵

题目大意:给定一个 N*M 的矩阵,现从 N 行中选出 R 行,M 列中选出 C 列,构成一个 R*C 子矩阵,求这个子矩阵相邻元素差的绝对值之和的最小值是多少。

题解:
发现是对行和列的组合生成,若直接暴力的话,时间复杂度为 \(O({n \choose r}{m \choose c}nm)\)
代码如下

#include 
using namespace std;
const int maxn=20;

int n,m,r,c,ans,mp[maxn][maxn];
vector row,col;

inline void calc(){
    int ret=0;
    for(int i=0;ic||col.size()+m-now+1r||row.size()+n-now+1

进一步考虑,发现若枚举出了 r 行,那么对于每一列来说,可以抽象成下列问题,即:给定一个长度为 N 的序列,现从序列中选出 M 个元素组成的子序列,使得这 M 个元素中相邻两个元素差的绝对值之和最小。发现是一个 dp,对于矩阵来说,将矩阵转化成序列即可,dp 的时间复杂度为 \(O(n^3)\)。总的时间复杂度为 \(O({n \choose r}m^3)\)

代码如下

#include 
#define cls(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=20;

int n,m,r,c,ans,mp[maxn][maxn];
vector row;
int dp[maxn][maxn],extra[maxn],cost[maxn][maxn];

inline void calc(){
    cls(dp,0x3f),cls(extra,0),cls(cost,0);
    for(int i=1;i<=m;i++)for(int j=i+1;j<=m;j++)for(auto ro:row)cost[i][j]+=abs(mp[ro][i]-mp[ro][j]);
    for(int co=1;co<=m;co++)for(int i=0;ir||row.size()+n-now+1

转载于:https://www.cnblogs.com/wzj-xhjbk/p/10840997.html

你可能感兴趣的:(【洛谷P2258】子矩阵)