题目大意

你需要保证第\(i\)天时有第\(a_i\)种书。你可以在任何一天买书,买第\(i\)种书的代价为\(c_i\)。

你最多同时拥有\(k\)本书,如果此时再买书,则必须先扔掉已拥有的一本书。并且如果以后用到那本书则需要重新购买。

问最小的代价使满足\(n\)天中的所有条件都满足。

\(medium : n,k \leq 400000\)且保证所有的\(c_i = 1\)

\(hard : n,k \leq 80\)

\(all : a_i \leq n,c_i \leq 10^6\)

题解

对于\(medium\)来说直接贪心就好。

每次需要删除的时候找出从当前位置往后最后一个出现的删除就好了。

调个\(set\)。注意不能用.(不要问我是怎么知道的)

主要问题在于\(hard\)。

\(n,k\)的范围又小了下来。

这提醒了我们已经不存在贪心的策略了。

不过我们可以从先前的贪心策略中得到启发。

如果我们只盯着一个存放书的位置上看,那么就是一个这个位子上的书不断变化的过程。

变化是为了去满足一些条件,也是因为要去满足下一个条件才变化的。

那么考虑如果将要满足的下一个条件确定了,那么这个位置在满足条件之前不会改变。

可以视作这个位置为了满足某个条件被占用了一段时间。

如果我们提前承受了所有的代价,那么下面我们就要处理收益问题。

这时候的收益即一个数在某一段时间保持不变只为下一次这个数出现的时候少一次购买。

所以我们可以建立这样的模型:

弧线边只连接上一个与其相同的数\(+1\)的位置和该点所在的位置。

还有要注意的一点是 : 不能让所有的流量都去满足其他条件限制

至少应该有一个流量留在主线上。

所以我们可以直接将输入的\(k--\)...

然后跑最小费用最大流即可.

\(medium:\)

#include <set>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-')ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
const int maxn = 400010;
int a[maxn],nx[maxn],ws[maxn];
set<int>s;
bool inq[maxn];int cnt = 0; int main(){
int n,k;read(n);read(k);
memset(ws,0x3f,sizeof ws);
rep(i,1,n) read(a[i]);
per(i,n,1){
nx[i] = ws[a[i]];
ws[a[i]] = i;
}
int ans = 0;
rep(i,1,n){
if(s.count(i)){
s.erase(i);
s.insert(nx[i]);
continue;
}
if(s.size() < k){
++ ans;
s.insert(nx[i]);
}else{
s.erase(--s.end());
s.insert(nx[i]);
++ ans;
}
}
printf("%d\n",ans);
return 0;
}

\(hard:\)

#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
const int maxn = 128;
const int maxnode = maxn;
const int maxedge = maxn*maxn;
const int inf = 0x3f3f3f3f;
struct Edge{
int to,next,cap,cost;
}G[maxedge<<1];
int head[maxnode],cnt = 1;
void add(int u,int v,int c,int d){
G[++cnt].to = v;
G[cnt].next = head[u];
head[u] = cnt;
G[cnt].cap = c;
G[cnt].cost = d;
}
inline void insert(int u,int v,int c,int d){
add(u,v,c,d);add(v,u,0,-d);
}
#define v G[i].to
int dis[maxn],flow[maxn],p[maxn];
bool inq[maxn];int S,T;
int ans;
inline bool spfa(){
queue<int>q;
memset(dis,0x3f,sizeof dis);
dis[S] = 0;flow[S] = inf;
inq[S] = true;
q.push(S);
while(!q.empty()){
int u = q.front();q.pop();
for(rg i = head[u];i;i=G[i].next){
if(dis[v] > dis[u] + G[i].cost && G[i].cap){
dis[v] = dis[u] + G[i].cost;
flow[v] = min(flow[u],G[i].cap);
p[v] = i;
if(!inq[v]){
q.push(v);
inq[v] = true;
}
}
}inq[u] = false;
}if(dis[T] == dis[0]) return false;
ans += dis[T]*flow[T];
for(rg u=T;u != S;u = G[p[u]^1].to)
G[p[u]].cap -= flow[T],G[p[u]^1].cap += flow[T];
return true;
}
#undef v
int a[maxn],c[maxn],ws[maxn];
int main(){
int n,k;read(n);read(k);
-- k;
rep(i,1,n) read(a[i]);
rep(i,1,n) read(c[i]);
S = n + 1;T = n+2;
insert(S,1,k,0);
insert(n,T,k,0);
rep(i,1,n-1) insert(i,i+1,k,0);
rep(i,1,n){
ans += c[a[i]];
if(ws[a[i]] != 0){
if(ws[a[i]]+1 == i) ans -= c[a[i]];
else insert(ws[a[i]]+1,i,1,-c[a[i]]);
}
ws[a[i]] = i;
}
while(spfa());
printf("%d\n",ans);
return 0;
}

Codeforces 802 ABC. Heidi and Library的更多相关文章

  1. 题解-CF802C Heidi and Library (hard)

    题面 CF802C Heidi and Library (hard) 有一个大小为 \(k\) 的空书架.有 \(n\) 天和 \(n\) 种书,每天要求书架中有书 \(a_i\).每天可以多次买书, ...

  2. 【CF802C】Heidi and Library(网络流)

    [CF802C]Heidi and Library(网络流) 题面 CF 洛谷 题解 前面两个Easy和Medium都是什么鬼玩意啊.... 不难发现如果这天的要求就是第\(a_i\)种书的话,那么\ ...

  3. 【CF802C】Heidi and Library (hard) 费用流

    [CF802C]Heidi and Library (hard) 题意:有n个人依次来借书,第i人来的时候要求书店里必须有种类为ai的书,种类为i的书要花费ci块钱购入.而书店的容量只有k,多余的书只 ...

  4. C. Heidi and Library (神奇的网络流)

    C. Heidi and Library 题意 有 n 种分别具有价格 b 的书 a ,图书馆里最多同时存放 k 本书,已知接下来 n 天每天都有一个人来看某一本书,如果图书馆里没有则需要购买,问最少 ...

  5. Codeforces 802 补题

    codeforces802 A-O Helvetic Coding Contest 2017 online mirror A  Heidi and Library (easy) 水题 同B #incl ...

  6. 贪心算法 Heidi and Library (easy)

    A. Heidi and Library (easy) time limit per test 2 seconds memory limit per test 256 megabytes input ...

  7. CF802C Heidi and Library hard 费用流 区间k覆盖问题

    LINK:Heidi and Library 先说一下简单版本的 就是权值都为1. 一直无脑加书 然后发现会引起冲突,可以发现此时需要扔掉一本书. 扔掉的话 可以考虑扔掉哪一本是最优的 可以发现扔掉n ...

  8. 【贪心】codeforces B. Heidi and Library (medium)

    http://codeforces.com/contest/802/problem/B [题意] 有一个图书馆,刚开始没有书,最多可容纳k本书:有n天,每天会有人借一本书,当天归还:如果图书馆有这个本 ...

  9. 【网络流】codeforces C. Heidi and Library (hard)

    http://codeforces.com/contest/802/problem/C

随机推荐

  1. 前端之 JQuery

    一.基本选择器 1.#id 概述: 根据给定的ID匹配一个元素. 使用任何的元字符(如 !"#$%&'()*+,./:;<=>?@[\]^`{|}~)作为名称的文本部分, ...

  2. PAT 天梯赛 L1-037. A除以B 【水】

    题目链接 https://www.patest.cn/contests/gplt/L1-037 AC代码 #include <iostream> #include <cstdio&g ...

  3. Oracle 9i Unix Manager

    在Unix上被迫终止ORACLE进程时,必须做以下事情: (1) 杀掉所有Oracle进程.    ps -ef|grep $ORACLE_SID|grep -v grep|awk '{print $ ...

  4. Go 语言defer用法

    defer延迟调用: 1.确保调用在函数结束时发生: 2.defer列表为先进后出: 3.通常在Open/Close  Lock/Unlock中使用. defer调用顺序示例: package mai ...

  5. mongodb 中的Multikey Index Bounds解释$elemMatch

    首先说一下 $elemMatch的用法: { _id: 1, results: [ 82, 85, 88 ] } { _id: 2, results: [ 75, 88, 89 ] } $elemMa ...

  6. Efficient Vector Representation for Documents through Corruption-by Minmin Chen阅读

    关键词: 词向量.文档向量.文档表示 地址:https://openreview.net/forum?id=B1Igu2ogg&noteId=B1Igu2ogg 首先,论文解决的是Word2V ...

  7. struts2 if标签示例[转]

    下面总结一下struts2 中if标签的使用 (1)判断字符串是否为空 <s:if test="user.username==null or user.username==''&quo ...

  8. 基于docker环境,搭建 jetty环境, 部署java项目

    前提: 1.Ubuntu 系统. 2.docker环境已经安装好. 实现步骤: 1.上docker hub 下载jetty docker 镜像. 执行命令:$ sudo docker pull jet ...

  9. eclipse和myeclipse的配置(基于工作空间)

    eclipse和myeclipse的配置是基于工作空间的,一旦工作空间发生改变,就需要重新配置. 以eclipse为例,新建工作空间后,选择Window--->Preferences: 1.在W ...

  10. wareshark网络协议分析之ARP

    一.ARP协议简介 简单的说ARP协议就是实现ip地址到物理地址的映射.当一台主机把以太网数据帧发送到位于同一局域网上的另一台主机时,是根据48bit的以太网地址(物理地址)来确定网络接口的. ARP ...