BZOJ1150 - [CTSC2007]数据备份Backup

2024-03-19 18:08

本文主要是介绍BZOJ1150 - [CTSC2007]数据备份Backup,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原题链接

Description

给出数轴上的n(n105)个点,要求从中选出k(kn/2)对点,使得每对点之间的距离之和最小。点的坐标范围为[0,109]

Solution

感觉挺巧妙的。容易知道每个点对必然是相邻的两个点,那么本题就相当于从n1个数中选出k个互不相邻的数,使得其和最小。
这里就要用到一个思想,姑且叫做反悔思想。大意就是当我们进行操作a后,加入另一个操作a,执行a就可以抵消a带来的影响,或者说撤销a
那么对于这道题来说,我们首先用链表来存储这n1个数和它们的前驱后继。我们每次选出最小的数At,将At加入ans,然后同时删除AtAt1At+1(因为选了At就不能选它们了)。然后我们加入一个数At1+At+1At,其前驱是At2,后继是At+2。当我们选择这个数的时候,就相当于放弃选择At,而是选择At1At2
举个例子:7,9,8,6,4,2,3,8Del 27,9,8,6,5(4+32),8Del 57,9,8,9(6+85) 可以看到当我们选择合并后的5后,ans=7=2+(4+32)=4+3{6,4,2,3,8}不可选,这就相当于选择了4,3这两个数。
因为我们每次都要取出最小的数,所以可以使用堆。

时间复杂度O(nlogn)

Code

//[CTSC2007]数据备份Backup
#include <cstdio>
#include <queue>
inline char gc()
{static char now[1<<16],*S,*T;if(S==T) {T=(S=now)+fread(now,1,1<<16,stdin); if(S==T) return EOF;}return *S++;
}
inline int read()
{int x=0; char ch=gc();while(ch<'0'||'9'<ch) ch=gc();while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();return x;
}
int const N=1e5+10;
int const INF=0x3F3F3F3F;
int n,k; int d[N];
bool del[N];
struct rec
{int id,len,pre,nxt;bool operator<(const rec x) const{return len>x.len;};
}r[N];
std::priority_queue<rec> Q;
int main()
{n=read(),k=read();for(int i=1;i<=n;i++) d[i]=read();r[0].id=0,r[0].len=INF,r[0].pre=0,r[0].nxt=1; Q.push(r[0]);r[n].id=n,r[n].len=INF,r[n].pre=n-1,r[n].nxt=n; Q.push(r[n]);for(int i=1;i<=n-1;i++){r[i].id=i; r[i].len=d[i+1]-d[i];r[i].pre=i-1,r[i].nxt=i+1;Q.push(r[i]);}int ans=0;while(k){int t=Q.top().id; Q.pop();if(del[t]) continue;ans+=r[t].len;int t1=r[t].pre,t2=r[t].nxt;k--; del[t1]=del[t2]=true;r[t].len=r[t1].len+r[t2].len-r[t].len;r[r[t].pre=r[t1].pre].nxt=t; r[r[t].nxt=r[t2].nxt].pre=t;Q.push(r[t]);}printf("%d\n",ans);return 0;
}

附上原60分网络流做法:

//[CTSC2007]数据备份Backup
#include <cstdio>
#include <cstring>
#include <queue>
inline char gc()
{static char now[1<<16],*S,*T;if(S==T) {T=(S=now)+fread(now,1,1<<16,stdin); if(S==T) return EOF;}return *S++;
}
inline int read()
{int x=0; char ch=gc();while(ch<'0'||'9'<ch) ch=gc();while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();return x;
}
int const N=1e5+10;
int const INF=0x3F3F3F3F;
int n,k,a[N];
int s,t,h[N],cnt;
struct edge{int v,c,w,nxt;} ed[N<<2];
void edAdd(int u,int v,int c,int w)
{cnt++; ed[cnt].v=v,ed[cnt].c=c,ed[cnt].w=w,ed[cnt].nxt=h[u],h[u]=cnt;cnt++; ed[cnt].v=u,ed[cnt].c=0,ed[cnt].w=-w,ed[cnt].nxt=h[v],h[v]=cnt;
}
int dst[N],pre[N];
std::queue<int> Q; bool in[N];
bool SPFA()
{memset(dst,0x3F,sizeof dst);Q.push(s),in[s]=true; dst[s]=0;while(!Q.empty()){int u=Q.front(); Q.pop(),in[u]=false;for(int i=h[u];i;i=ed[i].nxt){int v=ed[i].v,w=ed[i].w;if(ed[i].c&&dst[u]+w<dst[v]){dst[v]=dst[u]+w,pre[v]=i;if(!in[v]) Q.push(v),in[v]=true;}}}return dst[t]<INF;
}
int main()
{n=read(),k=read();for(int i=1;i<=n;i++) a[i]=read();s=0,t=n+2; cnt=1;for(int i=1;i<=n;i+=2){edAdd(s,i,1,0);if(i>1) edAdd(i,i-1,1,a[i]-a[i-1]);if(i<n) edAdd(i,i+1,1,a[i+1]-a[i]); }for(int i=2;i<=n;i+=2) edAdd(i,n+1,1,0);edAdd(n+1,t,k,0);int ans=0;while(SPFA()){for(int i=pre[t];i;i=pre[ed[i^1].v]) ed[i].c-=1,ed[i^1].c+=1;ans+=dst[t];}printf("%d\n",ans);return 0;
}

P.S.

咕咕咕了这么久…咸死我了
没想到傅里叶变换那篇阅读量居然1.5k啦!╰( ̄▽ ̄)╮

转载于:https://www.cnblogs.com/VisJiao/p/8485738.html

这篇关于BZOJ1150 - [CTSC2007]数据备份Backup的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

MySQL数据备份策略审计:确保数据安全与合规性

在企业环境中,数据备份策略的审计是确保数据安全、提高数据管理效率和满足合规要求的重要环节。MySQL作为广泛使用的数据库系统,其备份策略的审计可以帮助组织验证备份操作的有效性、监控备份过程并确保数据的完整性和可用性。本文将详细介绍如何在MySQL中实现数据备份的策略审计,包括审计的重要性、审计内容、审计工具和技术、以及审计策略的实施。 1. 审计数据备份策略的重要性 数据备份策略审计对于数据库

MySQL数据备份的版本控制:策略、实践与自动化

在数据库管理中,数据备份是确保数据安全性和可恢复性的关键步骤。随着数据量的不断增长,如何有效地管理这些备份,特别是实现数据备份的版本控制,成为了一个重要议题。MySQL作为广泛使用的数据库管理系统,提供了多种工具和策略来实现数据备份的版本控制。本文将深入探讨如何在MySQL中实现数据备份的版本控制,包括策略、实践和自动化方法。 1. 数据备份的版本控制概述 数据备份的版本控制是指对数据库备份进

MySQL数据备份策略性能监控:深入指南

在数据库管理中,数据备份的性能监控是确保备份操作高效、稳定运行的关键环节。MySQL作为流行的数据库系统,提供了多种工具和方法来监控备份策略的性能。通过监控,数据库管理员可以及时发现并解决备份过程中的性能瓶颈,优化备份策略,确保数据的安全性和完整性。本文将详细介绍如何在MySQL中实现数据备份的策略性能监控,包括监控的重要性、监控内容、监控工具和技术、以及监控策略的实施。 1. 监控数据备份策略

MySQL数据备份的存储管理:策略、实践与自动化

数据备份是数据库管理中的关键环节,它确保了在数据丢失或损坏的情况下能够恢复数据。在MySQL中,有效的数据备份存储管理不仅涉及到备份的创建,还包括备份的存储、组织、维护和验证。本文将详细介绍如何在MySQL中实现数据备份的存储管理,包括备份策略的制定、存储解决方案的选择、自动化备份流程的构建以及备份的验证和维护。 1. 数据备份存储管理的重要性 数据备份存储管理是确保数据备份有效性和可访问性的

构筑数据安全网:MySQL数据备份的故障转移策略

在企业数据管理中,数据备份的故障转移是确保业务连续性和数据完整性的关键环节。MySQL作为广泛使用的数据库系统,其数据备份的故障转移能力对于应对硬件故障、软件错误或自然灾害等突发事件至关重要。本文将深入探讨如何在MySQL中实现数据备份的故障转移,包括故障转移的概念、策略规划、实施步骤、监控和测试等方面。 1. 引言 故障转移,也称为故障恢复,是指在主要数据存储或服务遇到问题时,自动切换到备用

postgresql简单数据备份

文章目录 postgresql基本操作链接数据库基本命令数据库备份 postgresql基本操作 PostgreSQL是一个功能非常强大的、源代码开放的客户/服务器关系型数据库管理系统(RDBMS) python链接postgresql使用的包是psycopg2,zeone数据库的链接也是使用psycopg2。 链接数据库 免密操作后不需要 用户密码 psql -U 用

数据备份-linux之间同步目录和文件

文章目录 需求设计思路定时打包相关资源rsync同步介绍安装创建rsync用户目录服务器配置密码配置启动服务验证客户端 测试 inotify-tools 工具安装 完整脚本 需求 在软件开发与运维的过程中,数据远程同步不仅是保障业务连续性的关键步骤,也是灾难恢复计划不可或缺的一部分。 这一过程涉及将关键数据,包括文件、数据库、目录结构、定时打包的资源等,从生产环境安全、高效地传

数据安全守护者:精通数据备份与恢复的艺术

数据安全守护者:精通数据备份与恢复的艺术 在数字化时代,数据的价值不言而喻。然而,硬件故障、软件错误、人为操作失误甚至恶意攻击都可能威胁到数据的安全。因此,数据备份和恢复策略成为了保护数据不可或缺的手段。本文将深入探讨数据备份和恢复的方法,提供实用的指导和示例代码,确保你的数据安全无虞。 数据备份的重要性 数据备份是将数据复制到另一个位置的过程,以防止原始数据丢失或损坏。一个好的备份策略可以

redis数据备份的两种机制rdb aof

redis-server --port 6380redis-cli -h ip -p 6380object enconding key#返回key的实际数据类型bgrewriteaof重写aof文件去重 rdb容易丢数据 硬盘开销大 aof三种策略 always everysec no Redis的数据回写机制分同步和异步两种, 同步回写即SAVE命令,主进程直接向磁盘回写数据。在数

MySQL数据备份的分类

MySQL数据库的备份 在我们使用MySQL数据库的过程中,一些意外情况的发生,有可能造成数据的损失。例如,意外的停电,不小心的操作失误等都可能造成数据的丢失。 所以为了保证数据的安全与一致性,需要定期对数据进行备份。如果数据出现问题,就需要使用备份好的数据进行数据还原,这样可以将损失降至最低。 实际上,数据备份也是一种容灾,是指为防止系统出现操作失误或系统故障导致数据丢失,而将全部或部分数据集