CF573D-Bear and Cavalry【动态dp】
正题
题目链接:https://www.luogu.com.cn/problem/CF573D
题目大意
给出\(n\)个人\(n\)匹马,每个人/马有能力值\(w_i\)/\(h_i\)。
第\(i\)个人开始对应第\(i\)匹马,每个人不能选择对应的马,给每个人分配一个马后求最大的\(\sum w_i\times h_j\)。
每次交换两个人对应的马后求答案。
\(1\leq n\leq 30000,1\leq q\leq 10000\)
解题思路
设\(f_i\)表示匹配完前\(i\)匹马时的最大价值和。
考虑怎么转移,因为人和马一一对应,正常来说大的对大的乘积的和最大。但是如果恰好第\(i\)个人对应了第\(i\)匹马,那么显然\(i\)只能选择\(i+1\),而让\(i+1\)选择\(i\)。
然后还有一种情况是只有三个时,第一个人对应了第一匹马,上面的转移会使得最后一个人和最后一匹马无法匹配,故我们还需要考虑和第三个的匹配。
也就是\(f_i\)只会从\(f_{i-1},f_{i-2},f_{i-3}\)转移过来,所以上动态\(dp\)即可
时间复杂度\(O(3^3n\log n )\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=31000,inf=1e18,S=3;
struct matrix{
ll a[S][S];
}w[N<<4],c,tt;
struct node{
ll p,w;
}e[N],h[N];
ll n,m,id[N];
matrix operator*(const matrix &a,const matrix &b){
memset(c.a,0xcf,sizeof(c.a));
for(ll i=0;i<S;i++)
for(ll j=0;j<S;j++)
for(ll k=0;k<S;k++)
c.a[i][j]=max(c.a[i][j],a.a[i][k]+b.a[k][j]);
return c;
}
bool cmp(node x,node y){return x.w>y.w;}
void Change(ll x,ll L,ll R,ll pos,matrix &val){
if(L==R){w[x]=val;return;}
ll mid=(L+R)>>1;
if(pos<=mid)Change(x*2,L,mid,pos,val);
else Change(x*2+1,mid+1,R,pos,val);
w[x]=w[x*2]*w[x*2+1];
}
ll calc(ll l,ll r){
if(l<=0)return -inf;
ll n=r-l+1,c[4]={0,1,2,0},ans=-inf;
do{
ll sum=0;
for(ll j=0;j<n;j++){
if(e[l+c[j]].p==h[l+j].p){sum=-inf;break;}
sum=sum+e[l+c[j]].w*h[l+j].w;
}
ans=max(ans,sum);
}while(next_permutation(c,c+n));
return ans;
}
void Updata(ll x){
if(x>n)return;
memset(tt.a,0xcf,sizeof(tt.a));
tt.a[1][0]=0;tt.a[2][1]=0;
tt.a[0][2]=calc(x-2,x);
tt.a[1][2]=calc(x-1,x);
tt.a[2][2]=calc(x,x);
Change(1,1,n,x,tt);return;
}
signed main()
{
scanf("%lld%lld",&n,&m);
// memset(tt.a,0xcf,sizeof(tt.a));
// tt.a[0][0]=tt.a[1][1]=tt.a[2][2]=0;
// for(ll i=1;i<(N<<2);i++)w[i]=tt[i];
for(ll i=1;i<=n;i++)scanf("%lld",&e[i].w),e[i].p=i;
for(ll i=1;i<=n;i++)scanf("%lld",&h[i].w),h[i].p=i;
sort(e+1,e+1+n,cmp);
sort(h+1,h+1+n,cmp);
for(ll i=1;i<=n;i++)id[e[i].p]=i;
for(ll i=1;i<=n;i++)Updata(i);
while(m--){
ll l,r;
scanf("%lld%lld",&l,&r);
l=id[l];r=id[r];
swap(e[l].p,e[r].p);
for(ll i=0;i<3;i++)
Updata(l+i),Updata(r+i);
printf("%lld\n",w[1].a[2][2]);
}
return 0;
}
CF573D-Bear and Cavalry【动态dp】的更多相关文章
- 【CF573D】Bear and Cavalry 线段树
[CF573D]Bear and Cavalry 题意:有n个人和n匹马,第i个人对应第i匹马.第i个人能力值ai,第i匹马能力值bi,第i个人骑第j匹马的总能力值为ai*bj,整个军队的总能力值为$ ...
- 动态DP之全局平衡二叉树
目录 前置知识 全局平衡二叉树 大致介绍 建图过程 修改过程 询问过程 时间复杂度的证明 板题 前置知识 在学习如何使用全局平衡二叉树之前,你首先要知道如何使用树链剖分解决动态DP问题.这里仅做一个简 ...
- Luogu P4643 【模板】动态dp
题目链接 Luogu P4643 题解 猫锟在WC2018讲的黑科技--动态DP,就是一个画风正常的DP问题再加上一个动态修改操作,就像这道题一样.(这道题也是PPT中的例题) 动态DP的一个套路是把 ...
- 动态dp学习笔记
我们经常会遇到一些问题,是一些dp的模型,但是加上了什么待修改强制在线之类的,十分毒瘤,如果能有一个模式化的东西解决这类问题就会非常好. 给定一棵n个点的树,点带点权. 有m次操作,每次操作给定x,y ...
- 洛谷P4719 动态dp
动态DP其实挺简单一个东西. 把DP值的定义改成去掉重儿子之后的DP值. 重链上的答案就用线段树/lct维护,维护子段/矩阵都可以.其实本质上差不多... 修改的时候在log个线段树上修改.轻儿子所在 ...
- 动态 DP 学习笔记
不得不承认,去年提高组 D2T3 对动态 DP 起到了良好的普及效果. 动态 DP 主要用于解决一类问题.这类问题一般原本都是较为简单的树上 DP 问题,但是被套上了丧心病狂的修改点权的操作.举个例子 ...
- 动态dp初探
动态dp初探 动态区间最大子段和问题 给出长度为\(n\)的序列和\(m\)次操作,每次修改一个元素的值或查询区间的最大字段和(SP1714 GSS3). 设\(f[i]\)为以下标\(i\)结尾的最 ...
- [总结] 动态DP学习笔记
学习了一下动态DP 问题的来源: 给定一棵 \(n\) 个节点的树,点有点权,有 \(m\) 次修改单点点权的操作,回答每次操作之后的最大带权独立集大小. 首先一个显然的 \(O(nm)\) 的做法就 ...
- UOJ268 [清华集训2016] 数据交互 【动态DP】【堆】【树链剖分】【线段树】
题目分析: 不难发现可以用动态DP做. 题目相当于是要我求一条路径,所有与路径有交的链的代价加入进去,要求代价最大. 我们把链的代价分成两个部分:一部分将代价加入$LCA$之中,用$g$数组保存:另一 ...
随机推荐
- centos7上安装redis6-0-5
下载tar包 wget http://download.redis.io/releases/redis-6.0.5.tar.gz 解压tar包 tar -zxvf redis-6.0.5.tar.gz ...
- WPF Popup 右下角提示框 定时消失 ,以及任意位置定位
------------恢复内容开始------------ 好久没写WPF的博客了,其实有很多心得要总结下,但是懒..... 今天工作需要,需要实现一个 1 右下角的提示窗口,然后过三五秒自动消失这 ...
- linux 常用命令(五)——(centos7-centos6.8)JDK安装
1.安装jdk前先检测系统是否带有OpenJDK:若存在则删除 查看: java -version 查询出OpenJDK相关的文件:rpm -qa | grep java 删除OpenJDK相关的文件 ...
- Windows CMD .bat 批处理基础语法
格式 @echo off 代码..... pause 不会逐行将命令打印. rem [注释] 关键字注释. :: [注释] 符号注释. echo 打印到控制台. >> 输出重定向.追加. ...
- Linkerd 2.10(Step by Step)—配置超时
Linkerd 2.10 系列 快速上手 Linkerd v2 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traefik2 ...
- Java全栈方向学习路线
前端方向 前端基础 HTML --> https://www.w3school.com.cn/html/index.asp CSS --> https://www.w3school.com ...
- Linux·命令收藏
时间:2018-11-20 记录:byzqy 标题:Linux命令大全(手册) 地址:http://man.linuxde.net/ 标题:Linux script命令 -- 终端里的记录器 地址:h ...
- Kubernetes环境Traefik部署与应用
本作品由Galen Suen采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可.由原作者转载自个人站点. 概述 本文用于整理基于Kubernetes环境的Traefik部署与应用, ...
- 方法重载(Override)
什么是方法的重写(override 或 overwrite)? 子类继承父类以后,可以对父类中同名同参数的方法,进行覆盖操作. 应用: 重写以后,当创建子类对象以后,通过子类对象调用子父类中的同名同参 ...
- mybatis整理笔记
以下是idea2018辑编器 新建 Maven工程 1 file ->new ->project 新建后编程器在右下角加载插件.,这个时候需要会儿, 加载好后,软件目录会多一个ja包 ...