pre:在网格中,凸多边形可以按行(row)分解成若干段连续的区间 [ l , r ] ,且左端点纵坐标的值(col)满足先减后增,右端点纵坐标先增后减。

阶段:根据这个小发现,可以将阶段设置成每一行,因此,解决这个问题一共需要N个阶段。

状态:除了阶段外,表示每一个状态还需要记录下当前阶段下一共选了多少个网格,当前行选择的区间 [ l , r ] ,和相对于上一行来说端点选择的单调性。(0表示单调递增,1表示单调递减)

因此,状态可以表示成为\(dp[i][j][l][r][x][y]\)

状态转移方程:分成四种情况进行讨论,详见代码。

第二个要实现的是路径输出,可以额外使用与状态大小相同的数组来记录下当前状态是从哪个状态转移而来的,最后从末状态经过一次递归即可得到路径。

代码如下

#include <bits/stdc++.h>
#define forto(i,a,b) for(i=a;i<=b;i++)//循环宏定义,减小代码量
using namespace std; int n,m,k,sum[20][20];
int f[16][226][16][16][2][2];
struct node{
int l,r,x,y;
}pre[16][226][16][16][2][2]; void read_and_parse(){
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
scanf("%d",&sum[i][j]);
sum[i][j]+=sum[i][j-1];
}
} int x,y,i,j,l,r,ans,ai,al,ar,ax,ay;//本题状态数较多,因此采用当前变量全局化,避免参数传递混乱 inline void update(int dat,int L,int R,int X,int Y){
int& ans=f[i][j][l][r][x][y];//使用引用减小代码量
node& p=pre[i][j][l][r][x][y];
if(ans>=dat)return;
ans=dat;
p=(node){L,R,X,Y};
} void print(int i,int j,int l,int r,int x,int y){
if(!j)return;
node& p=pre[i][j][l][r][x][y];
print(i-1,j-(r-l+1),p.l,p.r,p.x,p.y);
forto(j,l,r)printf("%d %d\n",i,j);
} void solve(){
forto(i,1,n)forto(j,1,k)forto(l,1,m)forto(r,l,m){
int t=r-l+1;if(t>j)break;
int now=sum[i][r]-sum[i][l-1];
x=y=1;
for(int p=l;p<=r;p++)
for(int q=r;q<=m;q++){
update(f[i-1][j-t][p][q][1][0]+now,p,q,1,0);
update(f[i-1][j-t][p][q][1][1]+now,p,q,1,1);
}
x=1,y=0;
for(int p=l;p<=r;p++)
for(int q=p;q<=r;q++)
update(f[i-1][j-t][p][q][1][0]+now,p,q,1,0);
x=0,y=1;
for(int p=1;p<=l;p++)
for(int q=r;q<=m;q++){
update(f[i-1][j-t][p][q][1][1]+now,p,q,1,1);
update(f[i-1][j-t][p][q][1][0]+now,p,q,1,0);
update(f[i-1][j-t][p][q][0][1]+now,p,q,0,1);
update(f[i-1][j-t][p][q][0][0]+now,p,q,0,0);
}
x=y=0;
for(int p=1;p<=l;p++)
for(int q=l;q<=r;q++){
update(f[i-1][j-t][p][q][1][0]+now,p,q,1,0);
update(f[i-1][j-t][p][q][0][0]+now,p,q,0,0);
}
}
forto(i,1,n)forto(l,1,m)forto(r,l,m)forto(x,0,1)forto(y,0,1)
if(ans<f[i][k][l][r][x][y]){
ans=f[i][k][l][r][x][y];
ai=i,al=l,ar=r,ax=x,ay=y;
}
printf("Oil : %d\n",ans);
print(ai,k,al,ar,ax,ay);//传入终点状态参数
} int main(){
read_and_parse();
solve();
return 0;
}

【CH5104】I-country 线性dp+路径输出的更多相关文章

  1. 【洛谷P1854】花店橱窗 线性dp+路径输出

    题目大意:给定 N 个数字,编号分别从 1 - N,M 个位置,N 个数字按照相对大小顺序放在 M 个位置里,每个数放在每个位置上有一个对答案的贡献值,求一种摆放方式使得贡献值最大. 题解:一道典型的 ...

  2. P1052 过河 线性dp 路径压缩

    题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数 ...

  3. 选课 树形dp+路径输出

    #include<iostream> #include<cstdio> #include<cstring> #define maxn 2010 using name ...

  4. AcWing 313. 花店橱窗 (线性DP)打卡

    题目:https://www.acwing.com/problem/content/315/ 题意:有一个矩阵,你需要在每一行选择一个数,必须保证前一行的数的下标选择在下一行的左边,即下标有单调性,然 ...

  5. 机器分配----线性dp难题(对于我来说)

    题目: 总公司拥有高效设备M台, 准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值.其中M <= 15, ...

  6. 【线性DP】数字三角形

    题目链接 原题链接 题目描述 给定一个如下图所示的数字三角形,从顶部出发,在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点,一直走到底层,要求找出一条路径,使路径上的数字的和最大. 7 3 ...

  7. DP+路径 URAL 1029 Ministry

    题目传送门 /* 题意:就是从上到下,找到最短路,输出路径 DP+路径:状态转移方程:dp[i][j] = min (dp[i-1][j], dp[i][j-1], dp[i][j+1]) + a[[ ...

  8. 动态规划——线性dp

    我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...

  9. POJ1015 && UVA - 323 ~Jury Compromise(dp路径)

    In Frobnia, a far-away country, the verdicts in court trials are determined by a jury consisting of ...

随机推荐

  1. 【三】jquery之选择器

    转自:https://www.cnblogs.com/youfeng365/p/5846650.html jquery参考手册:http://jquery.cuishifeng.cn/index.ht ...

  2. JS模态框 简单案例

    演示: <!doctype html> <html lang="en"> <head> <meta charset="UTF-8 ...

  3. css及HTML知识点

    html : 180°  输出为 css:    margin: 0 auto;会在页面水平居中显示  box-shadow: 0 0 5px #f61818; 设置投影的位置大小颜色 outline ...

  4. React文档(十一)提升state

    经常有些组件需要映射同一个改变的数据.我们建议将共用的state提升至最近的同一个祖先元素.我们来看看这是怎样运作的. 在这一节中,我们会创建一个温度计算器来计算提供的水温是否足够沸腾. 我们先创建一 ...

  5. Canvas---clearRect()清除圆形区域

    function clearArcFun(x,y,r,cxt){ //(x,y)为要清除的圆的圆心,r为半径,cxt为context var stepClear=1;//别忘记这一步 clearArc ...

  6. Gitlab CR

    Gitlab 进行 CR 的强限制,原理很简单. 实现起来,利用的是 git 自身的 custom_hooks 的支持,以及需要对 gitlab 做一点操作,对它的数据库开放一个只读权限的账号,来处理 ...

  7. Wincc用户登录VBS脚本

    在Wincc中为防止未知用户的误操作,在操作性按钮以及图符等设备操作面板,在组流程图时,需设置用户权限,只有符合权限的用户才可以进行操作.所以在流程图界面需设置系统用户登录界面.登录操作可以选择按钮或 ...

  8. Runtime-消息发送和消息转发

    消息发送 消息发送举例:下面这个OC代码 [person read:book]; 会被编译成: objc_msgSend(person, @selector(read:), book); objc_m ...

  9. JS-使用indexof来统计字符出现次数

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

  10. Java WEB ----- 文件的上传

    最近学到的web阶段的文件的上传,就想记录一下,帮助自己复习以及帮助大家学习,一般我都会把上传的文件存到服务器中的web-inf 下面,因为这样用户不会直接访问到,我们存到数据库的一般都是路径.这里没 ...