正题

题目链接: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】的更多相关文章

  1. 【CF573D】Bear and Cavalry 线段树

    [CF573D]Bear and Cavalry 题意:有n个人和n匹马,第i个人对应第i匹马.第i个人能力值ai,第i匹马能力值bi,第i个人骑第j匹马的总能力值为ai*bj,整个军队的总能力值为$ ...

  2. 动态DP之全局平衡二叉树

    目录 前置知识 全局平衡二叉树 大致介绍 建图过程 修改过程 询问过程 时间复杂度的证明 板题 前置知识 在学习如何使用全局平衡二叉树之前,你首先要知道如何使用树链剖分解决动态DP问题.这里仅做一个简 ...

  3. Luogu P4643 【模板】动态dp

    题目链接 Luogu P4643 题解 猫锟在WC2018讲的黑科技--动态DP,就是一个画风正常的DP问题再加上一个动态修改操作,就像这道题一样.(这道题也是PPT中的例题) 动态DP的一个套路是把 ...

  4. 动态dp学习笔记

    我们经常会遇到一些问题,是一些dp的模型,但是加上了什么待修改强制在线之类的,十分毒瘤,如果能有一个模式化的东西解决这类问题就会非常好. 给定一棵n个点的树,点带点权. 有m次操作,每次操作给定x,y ...

  5. 洛谷P4719 动态dp

    动态DP其实挺简单一个东西. 把DP值的定义改成去掉重儿子之后的DP值. 重链上的答案就用线段树/lct维护,维护子段/矩阵都可以.其实本质上差不多... 修改的时候在log个线段树上修改.轻儿子所在 ...

  6. 动态 DP 学习笔记

    不得不承认,去年提高组 D2T3 对动态 DP 起到了良好的普及效果. 动态 DP 主要用于解决一类问题.这类问题一般原本都是较为简单的树上 DP 问题,但是被套上了丧心病狂的修改点权的操作.举个例子 ...

  7. 动态dp初探

    动态dp初探 动态区间最大子段和问题 给出长度为\(n\)的序列和\(m\)次操作,每次修改一个元素的值或查询区间的最大字段和(SP1714 GSS3). 设\(f[i]\)为以下标\(i\)结尾的最 ...

  8. [总结] 动态DP学习笔记

    学习了一下动态DP 问题的来源: 给定一棵 \(n\) 个节点的树,点有点权,有 \(m\) 次修改单点点权的操作,回答每次操作之后的最大带权独立集大小. 首先一个显然的 \(O(nm)\) 的做法就 ...

  9. UOJ268 [清华集训2016] 数据交互 【动态DP】【堆】【树链剖分】【线段树】

    题目分析: 不难发现可以用动态DP做. 题目相当于是要我求一条路径,所有与路径有交的链的代价加入进去,要求代价最大. 我们把链的代价分成两个部分:一部分将代价加入$LCA$之中,用$g$数组保存:另一 ...

随机推荐

  1. WPF 饼状图,柱形图,折线图 (2 折线图)

    折线图在柱形图的基础上,做了一些修改.大概效果和用法如下. X轴和Y轴的刻度,使用用了Path的Figures属性,绘制多条Figure+LineSegment完成. 同时,由于折线图很可能会画多条线 ...

  2. 安全|常见的Web攻击手段之CSRF攻击

    对于常规的Web攻击手段,如XSS.CRSF.SQL注入.(常规的不包括文件上传漏洞.DDoS攻击)等,防范措施相对来说比较容易,对症下药即可,比如XSS的防范需要转义掉输入的尖括号,防止CRSF攻击 ...

  3. git 的指定参考教程

    https://www.runoob.com/git/git-create-repository.html

  4. 【linux】vim常用命令

    转自:https://www.runoob.com/linux/linux-vim.html vi/vim 的使用 基本上 vi/vim 共分为三种模式,分别是命令模式(Command mode),输 ...

  5. qt 中的自定义pushbutton

  6. [ASP.NET MVC]@RenderSection,@RenderBody(),@RenderPage

    1.@RenderBody()  作用和母版页中的服务器控件类似,当创建基于此布局页面的视图时,视图的内容会和布局页面合并,而新创建视图的内容会通过布局页面的@RenderBody()方法呈现在标签之 ...

  7. 【OpenLayers】入门教程地址

    [OpenLayers]入门教程地址:  点击进入   http://anzhihun.coding.me/ol3-primer/index.html 简书地址 :  http://www.jians ...

  8. CentOS7中apache的部署与配置

    一.apache的部署 输入命令 yum list | grep httpd 查看可安装的软件包,选择"httpd.x86_64"安装. 输入命令 yum install http ...

  9. 微服务架构及raft协议

    微服务架构全景图 服务注册和发现 Client side implement 调用需要维护所有调用服务的地址 有一定的技术难度,需要rpc框架支持 Server side implement 架构简单 ...

  10. SpringBoot快速集成SpringBootAdmin管控台监控服务

    SpringBootAdmin是一个针对 Spring Boot 的 Actuator 接口进行 UI 美化封装的监控工具,它可以在列表中浏览所有被监控 spring-boot 项目的基本信息.详细的 ...