CH5104题解

CH5104:I-Country题解(线性DP)

MDZZ这道题调了2个小时自闭了((

题意简述

给你一个\(N*M\)的矩阵,每个格子都有一个权值。现在让你寻找一个包含\(K\)个格子的凸连通块,使得这个连通块的权值之和最大,求出这个最大的权值和,并给出连通块的具体方案

题意分析

这道题主要难理解的东西就是凸连通块

凸连通块是什么意思呢?就是整个图形的外轮廓不能突然凹下去一块,中间也不能有空缺。理性的说,任意两点连成的线段,如果经过图形,那么只能经过一个部分,不可能进去\(\to\)出来\(\to\)又进去。

总结:我们把这个连通块分成若干行,每行的左端点列号先递减,后递增;右端点列号先递增,后递减;满足单调性。

题目分析

这道题真的很F**K

首先,我们可以看出这是一道\(DP\)的题。

我们需要关注那些信息呢?

\((1)\).当前已经处理过了多少行;

\((2)\).已经选拔出了多少个格子;

\((3)\).当前行已选的格子的左端点——用于确定下一行左端点的可行范围;

\((4)\).当前行已选的格子的右端点——用于确定下一行右端点的可行范围;

\((5).\)当前左侧轮廓的单调性类型;

\((6).\)当前右侧轮廓的单调性类型;

好吧我得实话告诉你这些东西都要记录在\(dp\)数组中(啊这~)。

由此我们定义状态:\(dp_{i,j,l,r,x,y}\)

这个状态表示:前\(i\)行总共已经选了\(j\)个格子,其中第\(i\)行选择了第\(l\)到\(r\)个格子(均为\(0\)表示都不选),左边界的单调性为\(x\),右边界的单调性为\(y\)时能构成的连通块的最大权值之和。 (\(0\)表示递增,\(1\)表示递减)

这道题的状态转移方程挺好理解的,如下:

\((1).\)左边界的列号递减,右边界的列号递增(此时两个边界都处于扩张状态)

\(if \space \space j=r-l 1>0:\) \(dp_{i,j,l,r,1,0}=\sum^{r}_{p=l}A_{i,p} dp_{i-1,0,0,0,1,0}\)

\(if \space \space j>r-l 1>0:\) \(dp_{i,j,l,r,1,0}=\sum^{r}_{p=l}A_{i,p} max_{l\le p\le q\le r} {dp_{i-1,j-(r-l 1),p,q,1,0}}\)

\((2).\)左右的列号都递减(左边界扩张,右边界收缩)

\(dp_{i,j,l,r,1,1}=\sum^r_{p=l} \max_{l\le p \le r \le q} {\max_{0\le y \le 1}} {dp_{i-1,j-(r-l 1),p,q,1,y}}\)

\((3).\)左右的列号都递增(左边界收缩,右边界扩张)

\(dp_{i,j,l,r,0,0}=\sum^r_{p=l} \max_{p\le l \le q \le r} {\max_{0\le x \le 1}} {dp_{i-1,j-(r-l 1),p,q,x,0}}\)

\((4).\)左边界的列号递增,右边界的列号递减(此时两个边界都处于收缩状态)

\(dp_{i,j,l,r,0,1}={\sum^r_{p=l}A_{i,p} \max_{p\le l \le r \le q}{\max_{0\le x \le 1}}{\max_{0\le y\le 1}dp_{i-1,j-(r-l 1),p,q,x,y}}}\)

很明显初始状态\(dp_{i,0,0,0,1,0}=0\),目标状态是\(\max dp_{i,K,l,r,x,y}\),时间复杂度\(\Theta (NM^4K)=\Theta (N^2M^5)\)

#include<bits/stdc  .h>using namespace std;const int N=20;struct path{int i,k,l,fl,r,fr;}pre[N][N*N][N][2][N][2],anss;int n,m,K,ans;int mp[N][N],sum[N][N];int dp[N][N*N][N][2][N][2];void print(path x){if(x.l==x.r && x.l==0) return;for(int i=x.l;i<=x.r;i  ) printf("%d %d\n",x.i,i);print(pre[x.i][x.k][x.l][x.fl][x.r][x.fr]);}int read(){    int x=0,f=1;    char c=getchar();    while (c<'0'||c>'9')    {        if(c=='-') f=-1;        c=getchar();    }    while (c>='0'&&c<='9')    {        x=(x<<1) (x<<3) (c^48);        c=getchar();    }    return x*f;}int main(){scanf("%d%d%d",&n,&m,&K);for(int i=1;i<=n;i  ) for(int j=1;j<=m;j  ) mp[i][j]=read(),sum[i][j]=sum[i][j-1] mp[i][j];for(int i=1;i<=n;i  )    {        for(int k=1;k<=K;k  )        {            for(int l=1;l<=m;l  )            {                for(int r=l;r<=m;r  ){int len=r-l 1,val=sum[i][r]-sum[i][l-1];if(len>k) continue;if(len==k){dp[i][k][l][0][r][0]=val;pre[i][k][l][0][r][0]=path{0,0,0,0,0,0};if(dp[i][k][l][0][r][0]>ans){ans=dp[i][k][l][0][r][0];anss=path{i,k,l,0,r,0};}continue;}for(int l1=l;l1<=r;l1  )                    {                        for(int r1=l1;r1<=r;r1  ){int len1=r1-l1 1;if(len1>k-len) continue;if(dp[i-1][k-len][l1][0][r1][0] val>dp[i][k][l][0][r][0]){dp[i][k][l][0][r][0]=dp[i-1][k-len][l1][0][r1][0] val;pre[i][k][l][0][r][0]=path{i-1,k-len,l1,0,r1,0};}if(dp[i][k][l][0][r][0]>ans){ans=dp[i][k][l][0][r][0];anss=path{i,k,l,0,r,0};}}                    }//0 0for(int l1=1;l1<=l;l1  )                    {                        for(int r1=l;r1<=r;r1  ){int len1=r1-l1 1;if(len1>k-len) continue;if(dp[i-1][k-len][l1][0][r1][0] val>dp[i][k][l][1][r][0]){dp[i][k][l][1][r][0]=dp[i-1][k-len][l1][0][r1][0] val;pre[i][k][l][1][r][0]=path{i-1,k-len,l1,0,r1,0};}if(dp[i-1][k-len][l1][1][r1][0] val>dp[i][k][l][1][r][0]){dp[i][k][l][1][r][0]=dp[i-1][k-len][l1][1][r1][0] val;pre[i][k][l][1][r][0]=path{i-1,k-len,l1,1,r1,0};}if(dp[i][k][l][1][r][0]>ans){ans=dp[i][k][l][1][r][0];anss=path{i,k,l,1,r,0};}}                    }//1 0for(int l1=l;l1<=r;l1  )                    {                        for(int r1=r;r1<=m;r1  ){int len1=r1-l1 1;if(len1>k-len) continue;if(dp[i-1][k-len][l1][0][r1][0] val>dp[i][k][l][0][r][1]){dp[i][k][l][0][r][1]=dp[i-1][k-len][l1][0][r1][0] val;pre[i][k][l][0][r][1]=path{i-1,k-len,l1,0,r1,0};}if(dp[i-1][k-len][l1][0][r1][1] val>dp[i][k][l][0][r][1]){dp[i][k][l][0][r][1]=dp[i-1][k-len][l1][0][r1][1] val;pre[i][k][l][0][r][1]=path{i-1,k-len,l1,0,r1,1};}if(dp[i][k][l][0][r][1]>ans){ans=dp[i][k][l][0][r][1];anss=path{i,k,l,0,r,1};}}                    }//0 1for(int l1=1;l1<=l;l1  )                    {                        for(int r1=r;r1<=m;r1  ){int len1=r1-l1 1;if(len1>k-len) continue;if(dp[i-1][k-len][l1][0][r1][0] val>dp[i][k][l][1][r][1]){dp[i][k][l][1][r][1]=dp[i-1][k-len][l1][0][r1][0] val;pre[i][k][l][1][r][1]=path{i-1,k-len,l1,0,r1,0};}if(dp[i-1][k-len][l1][0][r1][1] val>dp[i][k][l][1][r][1]){dp[i][k][l][1][r][1]=dp[i-1][k-len][l1][0][r1][1] val;pre[i][k][l][1][r][1]=path{i-1,k-len,l1,0,r1,1};}if(dp[i-1][k-len][l1][1][r1][0] val>dp[i][k][l][1][r][1]){dp[i][k][l][1][r][1]=dp[i-1][k-len][l1][1][r1][0] val;pre[i][k][l][1][r][1]=path{i-1,k-len,l1,1,r1,0};}if(dp[i-1][k-len][l1][1][r1][1] val>dp[i][k][l][1][r][1]){dp[i][k][l][1][r][1]=dp[i-1][k-len][l1][1][r1][1] val;pre[i][k][l][1][r][1]=path{i-1,k-len,l1,1,r1,1};}if(dp[i][k][l][1][r][1]>ans){ans=dp[i][k][l][1][r][1];anss=path{i,k,l,1,r,1};}}                    }//1 1}            }        }    }printf("Oil : %d\n",ans);print(anss);return 0;}

来源:https://www.icode9.com/content-4-762451.html

(0)

相关推荐

  • 2021黄浦、崇明二模25题解法分析(构造X/A基本图形)

    2021黄浦.崇明二模25题主要围绕着构造A/X型,构建两组比例关系,从而助力问题解决.这类问题中往往隐含着"燕尾模型",通过合理添加辅助线,构造基本图形,借助线段间的比例关系(一 ...

  • 【2021中考】一道相似压轴题解法微探

    <怎样解题>一书的作者匈牙利数学家波利亚说过,掌握数学就意味着要善于解题.做题不在多而在精,题要解得精彩:对待解题的思想方法要对头,要通过做题,深刻理解概念,扎实掌握基本知识,学会运筹帷幄 ...

  • 2021浦东二模25题解法分析

    2021浦东二模25题以圆内接四边形为背景,综合考察了圆与正多边形(中心角),相似三角形的证明和性质以及等腰三角形的存在性问题,整道题的难度不大,辅助线的添加方法也是常规的连半径或做高解直角三角形. ...

  • 2.七年级数学下册:这题解二元一次方程,没想到有这招,整体代入好简单

    欢迎您来到方老师数学课堂,请点击上方的名片,关注方老师数学课堂.所有的视频内容,全部免费,请大家放心关注,放心订阅. 七年级数学下册:这题解二元一次方程,没想到有这招,整体代入好简单.大家先在草稿本上 ...

  • 2021徐汇二模25题解法分析

    2021徐汇二模25题以cos∠BAC=3/5,围绕"动"正方形和"动"正三角形,主要围绕构造直角三角形,利用锐角三角比解决问题. 2021徐汇二模25题解题背 ...

  • 《高中数学考点题解》考点真题目录

    <高中数学考点题解> 考点真题目录 (点击链接可看相关考点真题)  <数列>考点真题目录 [考点1]等差数列的判断与证明--定义法 [考点2]通项公式的推导过程及运用--累加法 ...

  • 《高中数学考点题解》考点目录

    <高中数学考点题解> 考点目录 (点击链接可看相关考点)  <数列>考点目录 [考点1]等差数列的判断与证明--定义法 [考点2]通项公式的推导过程及运用--累加法[考点3]通 ...

  • 2021年高考数学——导数专题解答题题型...

    2021年高考数学--导数专题解答题题型训练(培优系列,值得学习) 1.函数单调性讨论问题 2.函数与导数不等式问题(参数分离.放缩法.极值点偏移.) 3.导数与数列型不等式证明 4.方程与零点问题

  • 2021嘉定二模25题解法分析

    2021嘉定二模25题解题背景:2021嘉定二模的25题虽然是圆的背景,但是主要围绕着平行线分线段成比例定理(图1),X型基本图形(图2),以及勾股定理和垂径定理结合展开,本题的第三问在(1)和(2) ...