[AGC031E] Snuke the Phantom Thief
Problem Statement
A museum exhibits $N$ jewels, Jewel $1, 2, ..., N$.
The coordinates of Jewel $i$ are $(x_i, y_i)$ (the museum can be regarded as a two-dimensional plane), and the value of that jewel is $v_i$.
Snuke the thief will steal some of these jewels.
There are $M$ conditions, Condition $1, 2, ..., M$, that must be met when stealing jewels, or he will be caught by the detective.
Each condition has one of the following four forms:
- ($t_i$ =
L, $a_i$, $b_i$) : Snuke can only steal at most $b_i$ jewels whose $x$ coordinates are $a_i$ or smaller. - ($t_i$ =
R, $a_i$, $b_i$) : Snuke can only steal at most $b_i$ jewels whose $x$ coordinates are $a_i$ or larger. - ($t_i$ =
D, $a_i$, $b_i$) : Snuke can only steal at most $b_i$ jewels whose $y$ coordinates are $a_i$ or smaller. - ($t_i$ =
U, $a_i$, $b_i$) : Snuke can only steal at most $b_i$ jewels whose $y$ coordinates are $a_i$ or larger.
Find the maximum sum of values of jewels that Snuke the thief can steal.
Constraints
- $1 \leq N \leq 80$
- $1 \leq x_i, y_i \leq 100$
- $1 \leq v_i \leq 10^{15}$
- $1 \leq M \leq 320$
- $t_i$ is
L,R,UorD. - $1 \leq a_i \leq 100$
- $0 \leq b_i \leq N - 1$
- $(x_i, y_i)$ are pairwise distinct.
- $(t_i, a_i)$ are pairwise distinct.
- $(t_i, b_i)$ are pairwise distinct.
Input
Input is given from Standard Input in the following format:
$N$
$x_1$ $y_1$ $v_1$
$x_2$ $y_2$ $v_2$
$:$
$x_N$ $y_N$ $v_N$
$M$
$t_1$ $a_1$ $b_1$
$t_2$ $a_2$ $b_2$
$:$
$t_M$ $a_M$ $b_M$
Output
Print the maximum sum of values of jewels that Snuke the thief can steal.
Sample Input 1
7
1 3 6
1 5 9
3 1 8
4 3 8
6 2 9
5 4 11
5 7 10
4
L 3 1
R 2 3
D 5 3
U 4 2
Sample Output 1
36

Stealing Jewel $1, 5, 6$ and $7$ results in the total value of $36$.
Sample Input 2
3
1 2 3
4 5 6
7 8 9
1
L 100 0
Sample Output 2
0
Sample Input 3
4
1 1 10
1 2 11
2 1 12
2 2 13
3
L 8 3
L 9 2
L 10 1
Sample Output 3
13
Sample Input 4
10
66 47 71040136000
65 77 74799603000
80 53 91192869000
24 34 24931901000
91 78 49867703000
68 71 46108236000
46 73 74799603000
56 63 93122668000
32 51 71030136000
51 26 70912345000
21
L 51 1
L 7 0
U 47 4
R 92 0
R 91 1
D 53 2
R 65 3
D 13 0
U 63 3
L 68 3
D 47 1
L 91 5
R 32 4
L 66 2
L 80 4
D 77 4
U 73 1
D 78 5
U 26 5
R 80 2
R 24 5
Sample Output 4
305223377000
这个范围,基本上只要是多项式复杂度都能过得去了吧。
\(x\) 坐标小于等于 \(a_i\) 的至多有 \(b_i\) 个,这个条件很不友好。我们把他转换一下,这其实说明如果将所有选了的宝石按照 \(x\) 坐标从小到大排序,排名大于 \(b_i\) 的,\(x\) 坐标要大于 \(a_i\)。同理,坐标大于等于 \(a_i\) 的至多有 \(b_i\) 个的条件,我们可以转化成按 \(x\) 坐标从小到大排序之后,倒数排名要大于 \(b_i\) 的,\(x\) 坐标要小于等于 \(b_i\)。\(y\) 坐标同理。
这一个正着一个倒着的,怎么玩啊?反正 \(n\) 小的离谱,我们可以枚举一下总共选多少个数,然后可以求出 \(x\) 坐标排名为 \(i\) 的数 \(x\) 坐标的范围。\(y\) 坐标同理。
在求出 \(x\),\(y\) 排名第 \(i\) 的范围时,发现现在的问题转变为一个选数的问题,要给 \(x\) 排名第 \(i\) 的选一个坐标,然后还要给 \(y\) 排名第 \(i\) 的选一个坐标。这个问题就是经典的费用流模型了。
从源点连向表示 \(x\) 排名为第 \(i\) 个的点,流量1费用0,再从 \(x\) 排名第 \(i\) 个的点连向每个符合要求的坐标,流量1费用0。要把一个坐标拆成两个点,中间连流量1费用 \(v_i\)。如果他在 \(y\) 坐标可以排名第 \(i\),那么就从他连向表示 \(y\) 坐标排名第 \(i\) 的点,再连回汇点。
判断一下是否满流就行了。但我们想求最大费用,相当于取负后求最小费用,然后一起加一个 \(10^{15}\) 避免负环。最后答案减去 \(5\times i\times10^{15}\) 就行了,\(i\) 为现在枚举到的选宝石个数。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL INFLL=4e18,INFL=1e15+10;
const int N=505,T=N-1,S1=85,K=85,S2=170,S3=255,INF=2e9;
int hd[N],e_num(1),n,m,x[K],y[K],q[N*N*N],l,r,a[N],b[N],vhd[N],v[N],lx[K],ly[K],rx[K],ry[K],cnt;
char ch[N][5];
LL d[N],ret,ans,vv[N];
struct edge{
int v,nxt,f;
LL w;
}e[N*N*5];
void add_edge(int u,int v,int f,LL w)
{
e[++e_num]=(edge){v,hd[u],f,INFL-w};
hd[u]=e_num;
e[++e_num]=(edge){u,hd[v],0,w-INFL};
hd[v]=e_num;
}
int bfs()
{
memset(d,0x7f,sizeof(d));
memcpy(hd,vhd,sizeof(hd));
v[d[q[l=r=1]=0]=0]=1;
while(l<=r)
{
// printf("%d\n",q[l%N]);
for(int i=hd[q[l]];i;i=e[i].nxt)
{
// printf("%d\n",e[i].v);
if(d[e[i].v]>d[q[l]]+e[i].w&&e[i].f)
{
d[e[i].v]=d[q[l]]+e[i].w;
if(!v[e[i].v])
{
++r;
v[e[i].v]=1,q[r]=e[i].v;
}
}
}
v[q[l]]=0;
++l;
}
// printf("%lld\n",d[T]);,
return d[T]<INFLL;
}
int dfs(int x,int s)
{
if(x==T)
return s;
v[x]=1;
int g;
// printf("%d %d\n",x,s);
for(int&i=hd[x];i;i=e[i].nxt)
{
if(!v[e[i].v]&&e[i].f&&d[e[i].v]==d[x]+e[i].w&&(g=dfs(e[i].v,min(s,e[i].f))))
{
e[i].f-=g;
e[i^1].f+=g;
ans+=e[i].w*g;
v[x]=0;
return g;
}
}
v[x]=0;
return 0;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d%lld",x+i,y+i,vv+i);
scanf("%d",&m);
for(int i=1;i<=m;i++)
scanf("%s%d%d",ch[i],a+i,b+i);
for(int i=1;i<=n;i++)//枚举选多少个珠宝
{
// printf("%d\n",i);
e_num=1;
memset(hd,0,sizeof(hd));
memset(lx,0,sizeof(lx));
memset(rx,0x7f,sizeof(rx));
memset(ly,0,sizeof(ly));
memset(ry,0x7f,sizeof(ry));
for(int j=1;j<=n;j++)
add_edge(S2+j,S3+j,1,vv[j]);
for(int j=1;j<=i;j++)
{
add_edge(0,j,1,0);
add_edge(j+S1,T,1,0);
}
for(int j=1;j<=m;j++)
{
if(ch[j][0]=='L')
for(int k=b[j]+1;k<=i;k++)
lx[k]=max(lx[k],a[j]+1);
if(ch[j][0]=='R')
for(int k=1;k<=i-b[j];k++)
rx[k]=min(rx[k],a[j]-1);
if(ch[j][0]=='D')
for(int k=b[j]+1;k<=i;k++)
ly[k]=max(ly[k],a[j]+1);
if(ch[j][0]=='U')
for(int k=1;k<=i-b[j];k++)
ry[k]=min(ry[k],a[j]-1);
}
// for(int j=1;j<=i;j++)
// printf("%d %d %d %d\n",lx[j],rx[j],ly[j],ry[j]);
// puts("");
for(int j=1;j<=i;j++)
{
for(int k=1;k<=n;k++)
{
if(lx[j]<=x[k]&&x[k]<=rx[j])
add_edge(j,k+S2,1,0);
if(ly[j]<=y[k]&&y[k]<=ry[j])
add_edge(k+S3,j+S1,1,0);
}
}
ans=cnt=0;
memcpy(vhd,hd,sizeof(vhd));
int kk;
while(bfs())
while(kk=dfs(0,INF))
cnt+=kk;
if(cnt==i)
ret=max(ret,i*INFL*5-ans);
}
printf("%lld",ret);
}
[AGC031E] Snuke the Phantom Thief的更多相关文章
- 「题解」agc031_e Snuke the Phantom Thief
本文将同步发布于: 洛谷博客: csdn: 博客园: 简书. 题目 题目链接:洛谷 AT4695.AtCoder agc031_e. 题意简述 在二维平面上,有 \(n\) 颗珠宝,第 \(i\) 颗 ...
- HDOJ/HDU 1982 Kaitou Kid - The Phantom Thief (1)(字符串处理)
Problem Description Do you know Kaitou Kid? In the legend, Kaitou Kid is a master of disguise, and c ...
- HDU——1982Kaitou Kid - The Phantom Thief (1)(坑爹string题)
Kaitou Kid - The Phantom Thief (1) Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/327 ...
- 【HDOJ】1983 Kaitou Kid - The Phantom Thief (2)
不仅仅是DFS,还需要考虑可以走到终点.同时,需要进行预处理.至多封闭点数为起点和终点的非墙壁点的最小值. #include <iostream> #include <cstdio& ...
- HDU 1983 Kaitou Kid - The Phantom Thief (2)
神题,搜索太差,来自网络的题解与程序 思路: 封锁出口或者入口周围的格子. 最多需要4个封锁点. 所以我们可以采取这样的策略: 1.寻找一条盗贼的可行路线,如果没有,返回0. 2.计算封锁出口和入口四 ...
- 【AtCoder】AGC031
A - Colorful Subsequence 答案是 \(\prod_{c = 'a'}^{'z'} (cnt[c] + 1)\) #include <bits/stdc++.h> # ...
- AtCoder Grand Contest 031 简要题解
AtCoder Grand Contest 031 Atcoder A - Colorful Subsequence description 求\(s\)中本质不同子序列的个数模\(10^9+7\). ...
- AtCoder Grand Contest 031题解
题面 传送门 题解 比赛的之后做完\(AB\)就开始发呆了--简直菜的一笔啊-- \(A - Colorful\ Subsequence\) 如果第\(i\)个字母选,那么它前面任意一个别的字母的选择 ...
- HDU题解索引
HDU 1000 A + B Problem I/O HDU 1001 Sum Problem 数学 HDU 1002 A + B Problem II 高精度加法 HDU 1003 Maxsu ...
- codeforces 632+ E. Thief in a Shop
E. Thief in a Shop time limit per test 5 seconds memory limit per test 512 megabytes input standard ...
随机推荐
- Redis专题-秒杀
Redis专题-并发/秒杀 开局一张图,内容全靠"编". 昨天晚上在群友里看到有人在讨论库存并发的问题,看到这里我就决定写一篇关于redis秒杀的文章. 1.理论部分 我们看看一般 ...
- python机器学习经典算法代码示例及思维导图(数学建模必备)
最近几天学习了机器学习经典算法,通过此次学习入门了机器学习,并将经典算法的代码实现并记录下来,方便后续查找与使用. 这次记录主要分为两部分:第一部分是机器学习思维导图,以框架的形式描述机器学习开发流程 ...
- Redis系列21:缓存与数据库的数据一致性讨论
Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ...
- 谁家面试往死里问 Swagger 啊?
大家好,我是小富- 前言 说个挺奇葩的事,有个老铁给我发私信吐槽了一下它的面试经历,他去了个国企单位面试,然后面试官跟他就Swagger的问题聊了半个多小时.额- 面试嘛这些都不稀奇,总能遇到是千奇百 ...
- 解密Prompt系列14. LLM Agent之搜索应用设计:WebGPT & WebGLM & WebCPM
前两章,我们分别介绍了基于微调和prompt的工具调用方案,核心都是如何让大模型和工具进行交互,包括生成工具调用语句和处理工具调用请求.不过在实际应用中,想要设计一个可以落地的LLM Agent,需要 ...
- Spring Event 观察者模式, 业务解耦神器
观察者模式在实际开发过程中是非常常见的一种设计模式. Spring Event的原理就是观察者模式,只不过有Spring的加持,让我们更加方便的使用这一设计模式. 一.什么是观察者模式 概念: 观察者 ...
- window操作系统安装多个版本nodejs版本-控制工具nvm
参考: https://blog.csdn.net/m0_38134431/article/details/118388297 https://juejin.cn/post/7044890876631 ...
- MySQL中的Statistics等待
[作者] 吴宙旭,携程数据库专家 [问题描述] 线上我们偶尔会碰到MySQL的状态是statistics. 但如果出现大量的statistics等待,会引起MySQL性能急剧下降.官方的文档对这个状态 ...
- paramiko免密登陆
paramiko免密登陆 # -*- coding: utf-8 -*- import paramiko pkey='D:/pycharm_workspace/testpy/ssh_paramiko_ ...
- Flask框架——请求扩展、flask中间件、蓝图、分析线程和协程
文章目录 01 请求扩展 01 before_first_request :项目启动后第一次请求的时候执行 02 before_request:每次请求之前执行 03 after_request:每次 ...