P3842-DP【黄】
想搜索到最后一层,就必得先完成前面层的搜索任务,这构成了对状态转移的启示,即当前层的DP值应该是此前层转移过来后得到的最佳值。
但这道题看数据范围应该不能用二维数组,抱着侥幸的心理我使用了动态二维数组,dpij表示以第i层第j个为终点时的答案,结果MLE了,喜提42分,详见CODE-1。
后来意识到(其实是瞥了一眼题解后立刻受启发,然后想到的...)从中间节点转移过去是等价于先从边界节点动到中间节点在下去移动的,换句话说不需要存储、记录、判断那么多的状态,只需要存2*n个值就可以,但好像我写假了,不知为什么只有七十多分,详见CODE-2
总结,用记搜思想或者“想搜索到最后一层,就必得先完成前面层的搜索任务”等方法判断出所需的DP的下标的含义,然后在写出状态转移方程,这是我自己归纳的思考DP问题的一种比较简单的思维路径,应该多用用
CODE-1
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>
#include <unordered_map>
#include <cmath>
//#define int long long
using namespace std;
int * dp[20000+2];
int n,L[20000+2],R[20000+2];
int dfs(int row,int col)
{
if(col<L[row]||col>R[row])return 0;
if(dp[row][col-L[row]]!=-1)return dp[row][col-L[row]];
if(row==1)return dp[row][col-L[row]]=R[row]-1+R[row]-col;
int ANS=99999999;
for(int i=L[row-1];i<=R[row-1];i++)
{
if(i<=R[row]&&i>=L[row])
ANS=min(ANS,dfs(row-1,i)+1+2*(R[row]-max(i,col))+2*(min(i,col)-L[row])+max(i,col)-min(i,col));
else if(i>R[row]) ANS=min(ANS,dfs(row-1,i)+1+i-L[row]+col-L[row]);
else if(i<L[row]) ANS=min(ANS,dfs(row-1,i)+1+R[row]-i+R[row]-col);
}
return dp[row][col-L[row]]=ANS;
}
signed main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>L[i]>>R[i];
dp[i]=new int[R[i]-L[i]+1];
for(int j=0;j<R[i]-L[i]+1;j++)dp[i][j]=-1;//li~ri->0~ri-li
}
cout<<n-R[n]+dfs(n,R[n])<<endl;
return 0;
}
/*
dfs(n,R[n]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
printf("%3d",dfs(i,j));
}
cout<<endl;
}*/
CODE-2
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>
#include <unordered_map>
#include <cmath>
#define int long long
using namespace std;
int dp[20000+2][3];
int n,L[20000+2],R[20000+2];
int dfs(int row,int col)//now col is left or right
{
if(dp[row][col]!=-1)return dp[row][col];
int ANS=1e16;
if(col==1)//towards L[row]
{
//from L[row-1]
if(L[row-1]<=R[row])
ANS=min(ANS,dfs(row-1,1)+1+R[row]-L[row-1]+R[row]-L[row]);
else
ANS=min(ANS,dfs(row-1,1)+1+L[row-1]-L[row]);
//from R[row-1]
if(R[row-1]<=R[row])
ANS=min(ANS,dfs(row-1,2)+1+R[row]-R[row-1]+R[row]-L[row]);
else
ANS=min(ANS,dfs(row-1,2)+1+R[row-1]-L[row]);
}
else//towards R[row]
{
//from L[row-1]
if(L[row-1]<=L[row])
ANS=min(ANS,dfs(row-1,1)+1+R[row]-L[row-1]);
else
ANS=min(ANS,dfs(row-1,1)+1+L[row-1]-L[row]+R[row]-L[row]);
//from R[row-1]
if(R[row-1]<=L[row])
ANS=min(ANS,dfs(row-1,2)+1+R[row]-R[row-1]);
else
ANS=min(ANS,dfs(row-1,2)+1+R[row-1]-L[row]+R[row]-L[row]);
}
for(int i=L[row-1];i<=R[row-1]/2;i++)
{
if(i<=R[row]&&i>=L[row])
ANS=min(ANS,dfs(row-1,2)+R[row-1]-i+1+2*(R[row]-max(i,col))+2*(min(i,col)-L[row])+max(i,col)-min(i,col));
else if(i>R[row]) ANS=min(ANS,dfs(row-1,2)+1+i-L[row]+col-L[row]);
else if(i<L[row]) ANS=min(ANS,dfs(row-1,2)+1+R[row]-i+R[row]-col);
}
return dp[row][col]=ANS;
}
signed main()
{
scanf("%ld",&n);
for(int i=1;i<=n;i++)
{
scanf("%ld%ld",&L[i],&R[i]);
for(int j=0;j<3;j++)dp[i][j]=-1;//li~ri->0~ri-li
}
dp[1][1]=R[1]-1+R[1]-L[1];
dp[1][2]=R[1]-1;
cout<<min(n-R[n]+dfs(n,2),n-L[n]+dfs(n,1))<<endl;
return 0;
}
/*
dfs(n,R[n]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
printf("%3d",dfs(i,j));
}
cout<<endl;
}*/
P3842-DP【黄】的更多相关文章
- 【洛谷 P3842】[TJOI2007]线段(DP)
裸DP.感觉楼下的好复杂,我来补充一个易懂的题解. f[i][0]表示走完第i行且停在第i行的左端点最少用的步数 f[i][1]同理,停在右端点的最少步数. 那么转移就很简单了,走完当前行且停到左端点 ...
- DP擎天
DP! 黄题: 洛谷P2101 命运石之门的选择 假装是DP(分治 + ST表) CF 982C Cut 'em all! 树形贪心 洛谷P1020 导弹拦截 单调队列水题 绿题: 洛谷P1594 护 ...
- BestCoder Round #89 02单调队列优化dp
1.BestCoder Round #89 2.总结:4个题,只能做A.B,全都靠hack上分.. 01 HDU 5944 水 1.题意:一个字符串,求有多少组字符y,r,x的下标能组成等比数列 ...
- FZU 1025 状压dp 摆砖块
云峰菌曾经提到过的黄老师过去讲课时的摆砖块 那时百度了一下题目 想了想并没有想好怎么dp 就扔了 这两天想补动态规划知识 就去FZU做专题 然后又碰到了 就认真的想并且去做了 dp思想都在代码注释里 ...
- 合并傻子//区间dp
P1062 合并傻子 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 从前有一堆傻子,钟某人要合并他们~但是,合并傻子是要掉RP的...... 描述 在一个园 ...
- [BZOJ 2165] 大楼 【DP + 倍增 + 二进制】
题目链接:BZOJ - 2165 题目分析: 这道题我读了题之后就想不出来怎么做,题解也找不到,于是就请教了黄学长,黄学长立刻秒掉了这道题,然后我再看他的题解才写出来..Orz 使用 DP + 倍增 ...
- codeforces284 div1 B:概率dp
蛋疼的期末..好久没有A题了,,惭愧啊 昨晚打起精神准备做cf 结果竟然忘记注册了..拿学长号看了看题,今早起来补了一道dp 题目大意: 有n首歌,你需要边听边猜 对于第 i 首歌 每听一分钟你猜出它 ...
- 2017广东工业大学程序设计竞赛初赛 题解&源码(A,水 B,数学 C,二分 D,枚举 E,dp F,思维题 G,字符串处理 H,枚举)
Problem A: An easy problem Description Peter Manson owned a small house in an obscure street. It was ...
- BZOJ 2595: [Wc2008]游览计划 [DP 状压 斯坦纳树 spfa]【学习笔记】
传送门 题意:略 论文 <SPFA算法的优化及应用> http://www.cnblogs.com/lazycal/p/bzoj-2595.html 本题的核心就是求斯坦纳树: Stein ...
- BZOJ 1004: [HNOI2008]Cards [Polya 生成函数DP]
传送门 题意:三种颜色,规定使用每种颜色次数$r,g,b$,给出一个置换群,求多少种不等价着色 $m \le 60,\ r,g,b \le 20$ 咦,规定次数? <组合数学>上不是有生成 ...
随机推荐
- KR4-KP4
serdes测试中经常遇到KR4 和KP4, KR4指的是FEC 528 514对应25X4的100G KP4对应FEC 544 514,56/100x4 的200/400G链路 KP4应用比较广泛, ...
- [USACO2007OPENS] Fliptile S
题目描述 FJ 知道,智商高的奶牛产奶量也大,所以他为奶牛们准备了一个翻动瓦片的益智游戏. 在一个 \(M \times N\) 的方阵上(\(1 \leq M,N \leq 15\)),每个格子都有 ...
- Java在指定路径下执行cmd命令的方法
目前状态:毕业设计ing 背景: 做毕设时,由于需要将python的运行效果展示出来,所以使用了Java写了一个前端的界面.但是在使用Java对python的脚本进行调用时就尴尬了,出错-- 这里也许 ...
- 欧奈尔的RPS指标如何使用到股票预测
前言 1988年,欧奈尔将他的投资理念写成了<笑傲股市How to Make Money in Stocks>.书中总结了选股模式CANSLIM模型,每一个字母都代表一种尚未发动大涨势的潜 ...
- ElasticSearch之文件描述符的数量
ElasticSearch在运行过程中,涉及大量文件的打开.关闭.读.写等操作.因此当ElasticSearch进程的文件描述符数量不足时可能导致丢失数据等故障现象. 因此为保障ElasticSear ...
- Win11环境Mecab日语分词和词性分析以及动态库DLL not found问题(Python3.10)
日语因为存在假名,会导致翻译软件进行翻译时机翻味道过重的问题,比如積ん読(つんどく)这个词,大多数软件会翻译成:堆积的读,但其实是明明买了书却不读,光放着的意思.有时候也需要单独查句子中的单词释义来理 ...
- P1990-覆盖墙壁
分情况: \[\left\{ \begin{aligned} & 条形 \left\{ \begin{aligned} 横着\\ 竖着\\ \end{aligned}\right. \\ &a ...
- CSS 基础 2 - Box Model 盒模型
CSS 基础 2 - Box Model 盒模型 Box Model 盒模型是网页布局的前提.网页布局的几种方式: Table(过时):在 CSS 出现之前,一般用表格布局(将表格边框线隐藏) Flo ...
- flutter弹窗
AlertDialog: 优点:Material风格的弹窗,具有灵活的布局和样式自定义能力.易于使用,并提供了标题.内容和操作按钮的选项. 缺点:对于复杂的自定义布局和样式可能不够灵活. Bottom ...
- root无法下载
在 Linux 中,root 用户已经拥有系统中的最高权限.然而,如果你需要确保 root 用户具有所有权限,可以通过以下步骤来进行:(这是不对的) sudo chown -R root:root / ...