P1622 释放囚犯

2023-11-03 04:40
文章标签 释放 p1622 囚犯

本文主要是介绍P1622 释放囚犯,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

LOG P1622 释放囚犯

传送门(洛谷)

题目描述:
在这里插入图片描述输入数据:

20 3
3 6 14

输出数据:

35
分析:

容易看出,每次给犯人吃肉都是一个区间,则很容易得出此题为一个区间动归
区间动归的一般模板:f[i][j]=min(f[i][j],f[i][k-1]+f[k+1][j]+…)
这里的f[i][j]是表示放出i号到j号的犯人最少给的肉,而我们找中介点k的时候,是已经将i,j号的犯人放出了的,则有k号没有放出,所以最终的转移方程应是这个区间的人数减去自己,则为:
f[i][j]=min(f[i][j],f[i][k-1]+f[k+1][j]+a[j+1]-a[i-1]-1-1);
可以动手画一下图

Code

#include<bits/stdc++.h>
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
#define don(i,a,b) for(register int i=(a);i>=(b);i--)
#define ll long long
using namespace std;
const int maxn=1e6+10;
const int maxm=1e3+10;
int n,m;
int a[maxn],f[maxm][maxm];template <class t> inline void read(t &x)
{int f=1;x=0;char ch=getchar();while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}while(isdigit(ch)){x=10*x+ch-'0';ch=getchar();}x*=f;
}
/*--------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------*/void readdata()
{read(n),read(m);rep(i,1,m) read(a[i]);
}void work()
{sort(a+1,a+1+m);a[0]=0;a[m+1]=n+1;rep(l,1,m) {for(register int i=1;i+l-1<=m;i++) {int j=i+l-1;f[i][j]=INT_MAX;for(register int k=i;k<=j;k++)f[i][j]=min(f[i][j],f[i][k-1]+f[k+1][j]+a[j+1]-a[i-1]-1-1);}}printf("%d\n",f[1][m]);
}int main()
{freopen("input.txt","r",stdin);readdata();work();return 0;
}

给出记忆化搜索版的:
枚举区间人数 l , r l,r l,r
l o w e r b o u n d 和 u p p e r b o u n d lower_~bound和upper~bound lower boundupper bound找出在这个区间中有多少个可以放的人

解释为什么 u p p e r b o u n d ( a + 1 , a + m + 1 , r ) − a − 1 upper ~bound(a+1,a+m+1,r)-a-1 upper bound(a+1,a+m+1,r)a1
我们是在找区间 l − r l-r lr的小于 r r r的数,如果用 u p p e r b o u n d upper~bound upper bound则可能不存在,移到后面一下标,因此超出了 r r r的范围

#include<bits/stdc++.h>
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
#define don(i,a,b) for(register int i=(a);i>=(b);i--)
#define ll long long
using namespace std;
const int maxn=1e6+10;
const int maxm=1e3+10;
int n,m;
int a[maxn],f[maxm][maxm];template <class t> inline void read(t &x)
{int f=1;x=0;char ch=getchar();while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}while(isdigit(ch)){x=10*x+ch-'0';ch=getchar();}x*=f;
}
/*--------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------*/void readdata()
{read(n),read(m);rep(i,1,m) read(a[i]);
}inline int dfs(int l,int r) {if(f[l][r]!=-1) return f[l][r];if(l>r) return 0;int x=lower_bound(a+1,a+1+m,l)-a;int y=upper_bound(a+1,a+1+m,r)-a-1;if(x>y) return 0;f[l][r]=INT_MAX;rep(i,x,y) f[l][r]=min(f[l][r],dfs(l,a[i]-1)+dfs(a[i]+1,r)+r-l);return f[l][r];
}void work()
{sort(a+1,a+1+m);memset(f,-1,sizeof(f));a[0]=0;a[m+1]=n+1;printf("%d\n",dfs(1,n));
}int main()
{freopen("input.txt","r",stdin);readdata();work();return 0;
}

这篇关于P1622 释放囚犯的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/335648

相关文章

读锁的获取与释放是怎么实现的?

在 ReentrantReadWriteLock 中,读锁的获取与释放是通过管理读锁计数和线程状态来实现的。以下是更详细的说明,涵盖了读锁的获取与释放过程: 1. 读锁的获取 读锁获取的核心是允许多个线程同时持有读锁,只要没有线程持有写锁。 获取读锁的步骤 检查写锁状态:在获取读锁前,首先需要检查是否有线程持有写锁。如果没有线程持有写锁,当前线程可以安全地获取读锁。 增加读锁计数:如果

Linux - Tcp连接建立和释放的三次握手四次挥手

一、TCP报文段首部格式         源端口/目的端口:各占2个字节,分别写入源端口和目的端口,端口是传输层与应用层的服务接口    序号:占4个字节,TCP连接中传送的数据流中每一个字节都有一个序号,序号字段指本报文段所发送的数据的第一个字节的序号    确认号:占4个字节,是期望收到对方下一个报文的第一个数据字节的序号    数据偏移:占4个字节,它指出TCP报文的数据距离TCP

APK安装释放文件的过程

1、DDMS 在学习Android 应用程序安装相关文件的过程时,我们需要先了解一个工具DDMS( Dalvik Debug Monitor Service),即Android 开发环境中的Dalvik虚拟机调试监控服务。打开这个工具集有一个File Explorer(文件的浏览器),该文件浏览器可以帮助我们查看虚拟机上的所有文件。如图1-1所示: 2、Apk的安装

Java-互斥锁死锁释放锁

互斥锁         互斥锁(Mutex Lock)是一种同步机制,用于确保在任何时刻只有一个线程可以访问特定的代码段(临界区),从而防止数据竞争和不一致性。 使用方法: 在Java中,可以使用synchronized关键字或ReentrantLock类来实现互斥锁。使用lock()方法获取锁,使用unlock()方法释放锁。 特点: 确保线程安全,防止多个线程同时访问共享资源。简单易

Postgresql表和索引占用空间回收释放(表空间膨胀)

Postgresql表和索引占用空间回收释放(表空间膨胀) -- 1.创建测试表t_usercreate table if not exists t_user(id serial primary key,user_name varchar(255),pass_word varchar(255),create_time date,dr char(1));create index ind_ti

SAP CN22释放物料的可用性的操作方法

SAP PS系统,CN22要释放网络的可用性(直发物料号的需求), 必输要操作路径正确,或者操作的界面正确,否则保存后无法释放可用性。 先进入作业一览 然后进入作业的组件,对网络赋值的界面, 然后选中组建,再使用可用性-复位 然后保存即可。 只有在这个网络,对作业赋值的界面操作,才能释放可用性分配。 其他情况下,均不会生效。

数据库访问接口-数据源创建连接释放

(一)数据库编程组件间的关系示意图 (二)OLEDB编程基本框架和步骤 接口 IDBCreateSession总接口中CreateSession方法创建Session 对象Session的接口IDBCreateCommand接口中CreateCommand方法创建Command对象 Command对象接口ICommand接口中的Execute()创建Rowset对象。

【编程底层思考】线程阻塞时一定会释放cpu吗

线程阻塞时是否释放CPU取决于阻塞的原因和操作系统的行为。以下是一些具体情况: 1. 阻塞等待资源:当线程因为等待某个资源(如锁、信号量、条件变量等)而阻塞时,它通常会释放CPU,以便其他线程可以运行。在这种情况下,阻塞的线程不会占用CPU资源,直到它等待的资源变得可用。 2. 阻塞等待I/O操作:当线程因为等待I/O操作(如读取文件、网络通信等)而阻塞时,它也会释放CPU。操作系统会将线程挂

DIAMOND(DD)重新定义DeFi,释放新经济范式红利

近年来,DeFi作为区块链领域内屈指可数的“范式革命”代表,它所带来的观念更新和认知转变在时代潮流中显然尤为重要,而且极具里程碑式意义,称其为“第四次工业革命”也毫不为过。然而纵观DeFi从2020年野蛮生长到2021年回归理性的过程中,DeFi迄今为止还远远谈不上成功,其真正的高峰还尚未到来。 如同古希腊物理学家阿基米德曾说过:“给一个支点,可以撬起地球”,而这句话在DeFi身上也同样适用。虽

iOS面试:不手动指定autoreleasepool的前提下,一个autorealese对象在什么时刻释放?(比如在一个vc的viewDidLoad中创建)

在 iOS 开发中,当你在 viewDidLoad 方法中创建一个使用 autorelease 的对象时,这个对象的释放时机依赖于自动释放池(autorelease pool)如何被管理。在不手动指定 @autoreleasepool 的情况下,系统会在事件循环结束时自动处理这些对象。 释放时机解析 事件循环和自动释放池:每当一个方法调用(如 viewDidLoad)完成时,UIKit 会将控