P1622 释放囚犯
传送门
区间DP简介:
在写这题前,需要先弄清楚区间DP是如何操作的:
区间DP的做法还是相对固定的,没有其他类型DP的复杂多变。主要思想就是先在小区间进行DP得到最优解,然后再利用小区间的最优解合并求大区间的最优解。实现起来也十分简单,即枚举区间长度,再枚举左端点,之后枚举区间的断点进行转移。(不同的题目,有不同的转移方式)。
下面给出区间DP最简单形式的伪代码(具体要根据题目修改)
//mst(dp,0) 初始化DP数组
for(int i=;i<=n;i++)
{
dp[i][i]=初始值
}
for(int len=;len<=n;len++) //区间长度
for(int i=;i<=n;i++) //枚举起点
{
int j=i+len-; //区间终点
if(j>n) break; //越界结束
for(int k=i;k<j;k++) //枚举分割点,构造状态转移方程
{
dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+][j]+w[i][j]);
}
}
题解:
区间dp的套路:设 f [ i ] [ j ] 为区间释放 i ~ j 号囚犯所需最少的肉(注意, i , j 不是牢房编号,是释放的囚犯编号,也就是下面的 a [ i ] 数组)
枚举区间的分界点 k ,转移方程为:
f [ i ] [ j ] =min { f [ i ] [ j ] , f [ i ] [ k-1 ] + f [ k+1 ] [ j ] + a [ j+1 ] - a [ i-1 ] -1 -1 }
把后面这一块拿出来拆开看看, f [ i ] [ k-1 ] + f [ k+1 ] [ j ] + a [ j+1 ] - a [ i-1 ] -1 -1
f [ i ] [ k-1 ] + f [ k+1 ] [ j ],这个不必解释
a [ j+1 ] - a [ i-1 ] -1就是第 j+1 个要放出的囚犯到第 i-1 个要放出的囚犯之间的人数,也就是要发的肉的数量;
最后一个 -1 是什么呢,就是第k个放出去的囚犯,不用给他吃肉了
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<stack>
#include<queue>
#include<deque>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define INF 0x3f3f3f3f
#define maxn 2501
int n,m;
int a[maxn];
int f[maxn][maxn];
inline int read()
{
char kr=;
char ls;
for(;ls>''||ls<'';kr=ls,ls=getchar());
int xs=;
for(;ls>=''&&ls<='';ls=getchar())
{
xs=xs*+ls-;
}
if(kr=='-') xs=-xs;
return xs;
}
int main()
{
n=read();m=read();
for(int i=;i<=m;i++)
{
a[i]=read();
}
sort(a+,a+m+);//排序,有序的才能转移状态
a[]=;a[m+]=n+;//假设0和n+1号牢房有人,方便后面的状态转移(我就因为没有初始化输出负数)
for(int l=;l<=m;l++)//枚举区间长度
for(int i=;i+l-<=m;i++)//区间左端点位置
{
int j=i+l-;//区间右端点位置
f[i][j]=INF;
for(int k=i;k<=j;k++)//枚举分界点
f[i][j]=min(f[i][j],f[i][k-]+f[k+][j]+a[j+]-a[i-]--);
//状态转移
}
printf("%d\n",f[][m]);//输出
return ;
}
P1622 释放囚犯的更多相关文章
- P1622释放囚犯
这是一道绿题,是一道让人想用贪心但却是区间DP的题目,难倒了我这个蒟蒻. 这个题其实仔细观察是类似于石子合并的!合并石子的代价便是肉的数量,求最小代价.所以我们设dp[i][j]为释放第i个到第j个所 ...
- luogu P1622 释放囚犯
题目描述 Caima王国中有一个奇怪的监狱,这个监狱一共有P个牢房,这些牢房一字排开,第i个紧挨着第i+1个(最后一个除外).现在正好牢房是满的. 上级下发了一个释放名单,要求每天释放名单上的一个人. ...
- 洛谷P1622 释放囚犯
题目描述 Caima王国中有一个奇怪的监狱,这个监狱一共有P个牢房,这些牢房一字排开,第i个紧挨着第i+1个(最后一个除外).现在正好牢房是满的. 上级下发了一个释放名单,要求每天释放名单上的一个人. ...
- 洛谷P1622释放囚犯
题目: 这个题很明显是一个区间DP,但是比较不同的是,这个题它很像区间DP的经典题——石子合并. 然后我傻傻的搞了这个题搞了一下午,然后几乎看遍了全网的题解,就只看懂了这个方法,可能是我太菜了吧,但是 ...
- 【区间DP】释放囚犯
貌似和石子合并差不多 可能是我见的题太少了,所以都差不多 OK 算法分析 首先不难看出这是一道区间DP,那么,按照本蒟蒻的意思 区间DP==三个循环 for(int len=2;len<=n;l ...
- 贿赂囚犯 Bribe the prisoners ( 动态规划+剪枝)
一个监狱里有P个并排着的牢房,从左往右一次编号为1,2,-,P.最初所有牢房里面都住着一个囚犯.现在要释放一些囚犯.如果释放某个牢房里的囚犯,必须要贿赂两边所有的囚犯一个金币,直到监狱的两端或者空牢房 ...
- 【网易官方】极客战记(codecombat)攻略-地牢-囚犯
关卡连接: https://codecombat.163.com/play/level/the-prisoner 解放囚犯,你会得到盟友. 简介 敬请期待! 默认代码 # 释放囚犯,击败守卫并夺取宝石 ...
- DP の 百题大过关(5/100)
动态规划自古以来是DALAO凌虐萌新的分水岭,但有些OIer认为并没有这么重要--会打暴力,大不了记忆化.但是其实,动态规划学得好不好,可以彰显出一个OIerOIer的基本素养--能否富有逻辑地思 ...
- 【Java并发编程实战】----- AQS(二):获取锁、释放锁
上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...
随机推荐
- vue editorConfig
在文件目录下, indent_size = 2设置为4
- JS笔记—01
1.JS的代码一般在头部写2.当页面载入时,会执行位于body部分的JavaScript当被调用时,位于head部分的JavaScript被执行.3.要对外部的JS文件的一个变量操作,代码是写在内部J ...
- ES6知识整理(2)--变量的解构赋值
最近准备在业余空闲时间里一边学习ES6,一边整理相关知识.只有整理过的学习才是有效的学习.也就是学习之后要使用和整理成文,才是真正的学到了... 上一篇是一个试水,现在接上. 变量提升 看了下朋友回复 ...
- Docker学习笔记之Docker 的简历
0x00 概述 在了解虚拟化和容器技术后,我们就更容易理解 Docker 的相关知识了.在这一小节中,我将介绍关于 Docker 的出现和发展,Docker 背后的技术.同时,我们将阐述 Docker ...
- P4890 Never·island(dp)
P4890 Never·island 求门开的最小时间,其实也就是求门关的最大时间. 坐标这么大....显然坐标要离散化 离散化排序后,我们发现x轴被这些点划分成若干条线段$(l,r)$,并且有4种情 ...
- NATS—协议详解(nats-protocol)
NATS的协议是一个简单的.基于文本的发布/订阅风格的协议.客户端连接到 gnatsd(NATS服务器),并与 gnatsd 进行通信,通信基于普通的 TCP/IP 套接字,并定义了很小的操作集,换行 ...
- 13: vue项目结构搭建与开发
vue其他篇 01: vue.js安装 02: vue.js常用指令 03: vuejs 事件.模板.过滤器 目录: 1.1 初始化项目 1.2 配置API接口,模拟后台数据 1.3 项目整体结构化开 ...
- 20145221高其_Web基础
20145221高其_Web基础 目录 实践目标 Apache 前端编程 后端编程 PHP MYSQL & 后端 简单SQL注入与XSS 发帖和会话管理 总结 实践目标 (1)Web前端HTM ...
- CAN通信工作原理个人心得
CAN总线结构示意图: 说明: 1:CAN收发器(示意图中的单元)根据两总线CAN_H和CAN_L的电位差来判断总线电平: 2:实际中CAN_H与CAN_L由双绞线组成: 3:数据传递终端的电阻器,是 ...
- 【Python31--pickle函数】
一.含义 1.pickle的实质是什么 答:利用一些算法把数据对象转换成“二进制文件”,存储在硬盘上,当然也可以放在数据库或者是另外一台计算机上 2.存放:picking,读取:unpicking 3 ...