【CH5104】I-country 线性dp+路径输出
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+路径输出的更多相关文章
- 【洛谷P1854】花店橱窗 线性dp+路径输出
题目大意:给定 N 个数字,编号分别从 1 - N,M 个位置,N 个数字按照相对大小顺序放在 M 个位置里,每个数放在每个位置上有一个对答案的贡献值,求一种摆放方式使得贡献值最大. 题解:一道典型的 ...
- P1052 过河 线性dp 路径压缩
题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数 ...
- 选课 树形dp+路径输出
#include<iostream> #include<cstdio> #include<cstring> #define maxn 2010 using name ...
- AcWing 313. 花店橱窗 (线性DP)打卡
题目:https://www.acwing.com/problem/content/315/ 题意:有一个矩阵,你需要在每一行选择一个数,必须保证前一行的数的下标选择在下一行的左边,即下标有单调性,然 ...
- 机器分配----线性dp难题(对于我来说)
题目: 总公司拥有高效设备M台, 准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值.其中M <= 15, ...
- 【线性DP】数字三角形
题目链接 原题链接 题目描述 给定一个如下图所示的数字三角形,从顶部出发,在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点,一直走到底层,要求找出一条路径,使路径上的数字的和最大. 7 3 ...
- DP+路径 URAL 1029 Ministry
题目传送门 /* 题意:就是从上到下,找到最短路,输出路径 DP+路径:状态转移方程:dp[i][j] = min (dp[i-1][j], dp[i][j-1], dp[i][j+1]) + a[[ ...
- 动态规划——线性dp
我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...
- POJ1015 && UVA - 323 ~Jury Compromise(dp路径)
In Frobnia, a far-away country, the verdicts in court trials are determined by a jury consisting of ...
随机推荐
- C++ 将 std::string 转换为 char*
参考: std::string to char* C++ 将 std::string 转换为 char* 目前没有直接进行转换的方法.必须通过string对象的c_str()方法,获取C-style的 ...
- centos install jdk
=========== 查询jdk版本 ===========yum search jdk =========== 安装jdk 64位开发版 ===========yum -y install jav ...
- synchronized同步方法《二》
1.synchronized方法和锁对象 (1).验证线程锁的是对象 代码如下: 1.1创建一个MyObject类: package edu.ymm.about_thread4; public cla ...
- HihoCoder - 1142 ,三分入门
先来说说三分的思想: 从三分法的名字中我们可以猜到,三分法是对于需要逼近的区间做三等分: 我们发现lm这个点比rm要低,那么我们要找的最小点一定在[left,rm]之间.如果最低点在[rm,right ...
- 『Numpy』内存分析_numpy.dtype解析内存数据
numpy.dtype用于自定义数据类型,实际是指导python程序存取内存数据时的解析方式. [注意],更改格式不能使用 array.dtype=int32 这样的硬性更改,会不改变内存直接该边解析 ...
- 『TensorFlow』降噪自编码器设计
背景简介 TensorFlow实现讲解 设计新思路: 1.使用类来记录整个网络: 使用_init_()属性来记录 网络超参数 & 网络框架 & 训练过程 使用一个隐式方法初始化网络参数 ...
- centos7系统运行级别简介
centos7系统运行级别简介我们知道,centos6及之前的版本中,系统运行级别通过/etc/inittab文件进行设置和控制,但在centos7中,对这个文件的设置将不会对系统运行级别产生影响,这 ...
- mysql和mariadb支持insert delayed的问题
分析一个开源项目,往数据库里添加日志,为了避免写入日志信息影响正常业务,日志的插入方式采用了insert delayed的方式. 打印其数据库语句,复制到mysql执行报如下错误: ERROR 161 ...
- 31 位域、空类的sizeof值
1 分析下列程序: #include<iostream> using namespace std; struct s { int x: 3; int y: 4; int z: 5; dou ...
- 曾经觉得学习晦涩难懂的我是如何爱上linux的
2016年冬天,我已经是一名学习计算机科学与技术专业的大三的“老腊肉”了,但是当时的水平依旧平平.就在2016年快要结束的时候,我周围的同学们被一股考研和工作的压力炸开了锅,我也在默默思考着我的人生, ...