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, U or D.
  • $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的更多相关文章

  1. 「题解」agc031_e Snuke the Phantom Thief

    本文将同步发布于: 洛谷博客: csdn: 博客园: 简书. 题目 题目链接:洛谷 AT4695.AtCoder agc031_e. 题意简述 在二维平面上,有 \(n\) 颗珠宝,第 \(i\) 颗 ...

  2. 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 ...

  3. 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 ...

  4. 【HDOJ】1983 Kaitou Kid - The Phantom Thief (2)

    不仅仅是DFS,还需要考虑可以走到终点.同时,需要进行预处理.至多封闭点数为起点和终点的非墙壁点的最小值. #include <iostream> #include <cstdio& ...

  5. HDU 1983 Kaitou Kid - The Phantom Thief (2)

    神题,搜索太差,来自网络的题解与程序 思路: 封锁出口或者入口周围的格子. 最多需要4个封锁点. 所以我们可以采取这样的策略: 1.寻找一条盗贼的可行路线,如果没有,返回0. 2.计算封锁出口和入口四 ...

  6. 【AtCoder】AGC031

    A - Colorful Subsequence 答案是 \(\prod_{c = 'a'}^{'z'} (cnt[c] + 1)\) #include <bits/stdc++.h> # ...

  7. AtCoder Grand Contest 031 简要题解

    AtCoder Grand Contest 031 Atcoder A - Colorful Subsequence description 求\(s\)中本质不同子序列的个数模\(10^9+7\). ...

  8. AtCoder Grand Contest 031题解

    题面 传送门 题解 比赛的之后做完\(AB\)就开始发呆了--简直菜的一笔啊-- \(A - Colorful\ Subsequence\) 如果第\(i\)个字母选,那么它前面任意一个别的字母的选择 ...

  9. HDU题解索引

    HDU 1000 A + B Problem  I/O HDU 1001 Sum Problem  数学 HDU 1002 A + B Problem II  高精度加法 HDU 1003 Maxsu ...

  10. 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 ...

随机推荐

  1. 03.前后端分离中台框架 zhontai 项目代码生成器的使用

    zhontai 项目 基于 .Net7.x + Vue 等技术的前后端分离后台权限管理系统,想你所想的开发理念,希望减少工作量,帮助大家实现快速开发 后端地址:https://github.com/z ...

  2. k8s发布应用

    前言 首先以SpringBoot应用为例介绍一下k8s的发布步骤. 1.从代码仓库下载代码,比如GitLab: 2.接着是进行打包,比如使用Maven: 3.编写Dockerfile文件,把步骤2产生 ...

  3. 拼多多sku详情的获取分析以及应用

    一.拼多多sku详情获取方式 要获取拼多多SKU详情,需要使用拼多多的API接口,以下是获取拼多多SKU详情的步骤: 1.注册拼多多开放平台账户并创建应用 拼多多创建开发者账户并创建应用,获得应用ID ...

  4. PYQT5学习(12)Qtabwidget 选项卡及其窗口,Qstackedwidget和Qtabwidget的效果类似,以及系统托盘QsystemtrayIcon

    参考博文:https://blog.csdn.net/jia666666/article/details/81669092QTabWidget控件提供一个选项卡和一个页面区域,默认显示第一个选项卡的页 ...

  5. SQL-报错注入

    updatexml报错注入 updatexml (XML_document, XPath_string, new_value): 第一个参数:XML_document是String格式,为XML文档对 ...

  6. 解密Prompt系列17. LLM对齐方案再升级 WizardLM & BackTranslation & SELF-ALIGN

    话接上文的指令微调的样本优化方案,上一章是通过多样性筛选和质量过滤,对样本量进行缩减,主打经济实惠.这一章是通过扩写,改写,以及回译等半监督样本挖掘方案对种子样本进行扩充,提高种子指令样本的多样性和复 ...

  7. 全面掌握胶囊网络:从基础理论到PyTorch实战

    本文全面深入地探讨了胶囊网络(Capsule Networks)的原理.构建块.数学模型以及在PyTorch中的实现.通过本文,读者不仅能够理解胶囊网络的基础概念和高级数学原理,还能掌握其在实际问题中 ...

  8. TerraMoursGPT V1.0 开发总结

    TerraMoursGPT V1.0 开发总结 TerraMoursGPT V1.0 是之前gpt项目基于TerraMours后端框架的重构,实现用户登陆和基于SK的多语言模型聊天.基于chatgpt ...

  9. liunx远程管理常用命令笔记

    1,关机/重启 shutdown -r now : 立刻重启的命令 2,查看或配置网卡信息 2.1  网卡和 IP 地址 2.2  ifconfig 用了管道和grep 查找到 IP 地址 2.3 p ...

  10. List 切割成小 list 分批处理数据

    使用 Google Guava 库中的方法对 bmList 进行分割. Lists.partition() 方法用于将一个列表按指定大小进行分割,返回一个包含分割后子列表的新列表. 在这个例子中,bm ...