区间 DP 专场:愉快爆炸

T1

题目大意

有 \(n\) 个有颜色的块,连续 \(k\) 个相同颜色的就可以消掉

现在可以在任意位置插入任意颜色的方块,问最少插入多少个可以全部抵消

题解

先把连续的化成一块,问题变为如何消掉一块。 \(num\) 为个数, \(color\) 为颜色

设 \(F_{i,j,len}\) 表示表示 \([i,j]\) 后面有 \(len\) 个和 \(j\) 颜色一样的与 \(j\) 一起消除。

初始 \(F_{i,i,len}=\max(0,k-num_i-len)\)

然后 \(F_{i,j,len}=F_{i,j-1,0}+\max(0,k-num_j-len)\) 即单独消去

枚举中转点 \(k'\) ,\(F_{i,j,len}=\min_{k'=i}^{j-1}F_{i,k',\min(k,len+num_j)}+F_{k+1,j-1,0} (color_j=color_{k'})\)

就是先消掉 \([k+1,j-1]\) 然后再将第 \(j\) 块与 \(i,k\) 一起操作

目标: \(F_{1,n,0}\)

#include<bits/stdc++.h>
using namespace std;
const int N=105;
int n,K,x[N],cl[N],w[N],tot;
int f[N][N][10];
int main() {
scanf("%d%d",&n,&K);
for(int i=1;i<=n;i++)scanf("%d",&x[i]);
cl[1]=x[1],w[1]=tot=1;
for(int i=2;i<=n;i++) {
if(x[i]^x[i-1]) {
++tot,cl[tot]=x[i],w[tot]=1;
} else ++w[tot];
}
memset(f,100,sizeof(f));
n=tot;
for(int i=1;i<=n;i++)
for(int l=0;l<=K;l++)
f[i][i][l]=max(0,K-w[i]-l);
for(int l=2;l<=n;l++)
for(int i=1,j=l;j<=n;i++,j++)
for(int le=0;le<=K;le++) {
f[i][j][le]=f[i][j-1][0]+max(0,K-w[j]-le);
for(int k=i;k<j;k++)
if(cl[j]==cl[k])
f[i][j][le]=min(f[i][j][le],f[i][k][min(le+w[j],K)]+f[k+1][j-1][0]);
}
printf("%d",f[1][n][0]);
return 0;
}

总结

这道题想到了 \(\text{dp}\) 却没有想到区间,更没有想到多设 \([len]\) 这一维

下次要学会通过多一个状态处理转移的错误

T2

题目大意

给你 \(n\) 个 \(a_i\times b_i\) 的矩阵,问乘在一起最少要多少次乘法

输入确保能够相乘

题解

因为输入确保能够相乘,其实就是一个区间 \(\text{dp}\)

枚举中转点 \(k\) 时,这个区间 \([i,j]\) 的贡献是 \(x_i\cdot y_k\cdot y_j\)

#include<bits/stdc++.h>
using namespace std;
const int N=505;
int n,x[N],y[N],f[N][N];
int main() {
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d%d",&x[i],&y[i]);
for(int l=2;l<=n;l++)
for(int i=1,j=l;j<=n;i++,j++) {
f[i][j]=2100000000;
for(int k=i;k<=j;k++)
f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+x[i]*y[k]*y[j]);
}
printf("%d",f[1][n]);
}

总结

这题以为是贪心,因为没有认真想提示的含义

T3

题目大意

给你一圈数,取一个数的贡献是这个数和其左边、右边的数的积

最后拿完只有两个数,问最大得分和最小得分的差

题解

  1. 断环成列
  2. 枚举区间 \([i,j]\) 中的最后取得数 \(k\in[i,j)\) 那么贡献为 \(a_i\cdot a_{k+1}\cdot a_{j+1}\)
#include<bits/stdc++.h>
using namespace std;
const int N=205;
int n,x[N],f[N][N],g[N][N];
int mx,mn=2100000000;
int main() {
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&x[i]),x[i+n]=x[i];
for(int l=2;l<=n;l++) {
for(int i=1,j=l;j<=(n<<1);i++,j++) {
f[i][j]=2100000000;
for(int k=i;k<j;k++) {
g[i][j]=max(g[i][j],g[i][k]+g[k+1][j]+x[i]*x[k+1]*x[j+1]);
f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+x[i]*x[k+1]*x[j+1]);
}
}
}
for(int i=1;i<=n;i++)
mx=max(mx,g[i][i+n-2]),
mn=min(mn,f[i][i+n-2]);
printf("%d",mx-mn);
}

总结

这题不知道如何计算贡献,多想想状态的含义

T4

题目大意

\(n\) 个整数组成的圆环,\(i,j\) 的距离为两个格子之间的格子数的最小值

有一个开始指向 1 的指针,取一个数的代价即这个数的值

开始可取下指针所指的那个数以及与这个格子距离小于 \(k\) 的数

可以转动,每次转由一个格子转向其相邻的格子,且代价为圆环上还剩下的数的最大值

题解

所有各自都是要取得,至少需要 \(\sum_{i=1}^n a_i\)

开始可以取走距离小于 \(k\) 的,就是 \([1,k+1],[k,n]\) 全都没了

问题变成一个取完所有数的最小花费,用区间 \(DP\)

设 \(f_{i,j}\) 为从 \(i\) 取到 \(j\) 的最小话费,所以 \(f_{i,j}\ne f_{j,i}\)

区间最大可以预处理为 \(mx_{i,j}\)

\(f_{i,j}=\min(f_{i+1,j}+mx_{i,j},f_{j-1,i}+(len[1,i]+len[j,n])*mx_{i,j})\)

\(f_{i,j}=\min(f_{i-1,j}+mx_{i,j},f_{j+1,i}+(len[1,j]+len[i,n])*mx_{i,j})\)

就是一种正来一种反来

#include<bits/stdc++.h>
using namespace std;
const int N=2005;
int n,K,ans,x[N],f[N][N],mx[N][N];
int main() {
scanf("%d%d",&n,&K);
memset(f,100,sizeof(f));
for(int i=1;i<=n;i++) {
scanf("%d",&x[i]);
ans+=x[i];
mx[i][i]=f[i][i]=x[i];
}
if(n<=K+K+1)return printf("%d",ans),0;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
mx[i][j]=mx[j][i]=max(mx[i][j-1],x[j]);
for(int l=1;l<n-K-K;l++) {
for(int i=K+2,j=i+l;j<=n-K;i++,j++)
f[i][j]=min(f[i+1][j]+mx[i][j],f[j-1][i]+(i-K-1 + n-K-j)*mx[i][j]);
for(int i=n-K,j=i-l;j>=K+2;i--,j--)
f[i][j]=min(f[i-1][j]+mx[i][j],f[j+1][i]+(j-K-1 + n-K-i)*mx[i][j]);
}
ans+=min(f[n-K][K+2],f[K+2][n-K]);
printf("%d",ans);
}

总结

这道题确实是比较好,要学会转换问题

End

这次区间 \(dp\) 给本蒟蒻敲响警钟,要注意了

2021.03.20【NOIP提高B组】模拟 总结的更多相关文章

  1. 5820. 【NOIP提高A组模拟2018.8.16】 非法输入(模拟,字符串)

    5820. [NOIP提高A组模拟2018.8.16] 非法输入 (File IO): input:aplusb.in output:aplusb.out Time Limits: 1000 ms   ...

  2. JZOJ 5818. 【NOIP提高A组模拟2018.8.15】 做运动

    5818. [NOIP提高A组模拟2018.8.15] 做运动 (File IO): input:running.in output:running.out Time Limits: 2000 ms  ...

  3. JZOJ 5812. 【NOIP提高A组模拟2018.8.14】 区间

    5812. [NOIP提高A组模拟2018.8.14] 区间 (File IO): input:range.in output:range.out Time Limits: 1000 ms  Memo ...

  4. 2021.04.03【NOIP提高B组】模拟 总结

    T1 题目大意:求最小的 \(n\in[0,lim]\) 使得区间 \([L,R]\) 在线段树建树 \(build(0,n)\) 的区间内 考场时想到了正解,结果推式子退错了... 其实就是从下往上 ...

  5. 2021.05.03【NOIP提高B组】模拟 总结

    比较水的一场比赛,却不能 AK T1 有 \(n\) 次,每次给 \(A_i,B_i\) 问以 \(i\) 结尾的 \(A,B\) 的匹配中最大和的最小值 问最大和的最小值,却不用二分. 如果暴力排序 ...

  6. [JZOJ5817] 【NOIP提高A组模拟2018.8.15】 抄代码

    Description J 君是机房的红太阳,每次模拟她总是 AK 虐场.然而在 NOIP2117 中,居然出现了另一位 AK 的选手 C 君! 这引起了组委会的怀疑,组委会认为 C 君有抄袭 J 君 ...

  7. [jzoj 5782]【NOIP提高A组模拟2018.8.8】 城市猎人 (并查集按秩合并+复杂度分析)

    传送门 Description 有n个城市,标号为1到n,修建道路花费m天,第i天时,若gcd(a,b)=m-i+1,则标号为a的城市和标号为b的城市会建好一条直接相连的道路,有多次询问,每次询问某两 ...

  8. [jzoj 5778]【NOIP提高A组模拟2018.8.8】没有硝烟的战争 (博弈论+dp)

    传送门 Description 被污染的灰灰草原上有羊和狼.有N只动物围成一圈,每只动物是羊或狼. 该游戏从其中的一只动物开始,报出[1,K]区间的整数,若上一只动物报出的数是x,下一只动物可以报[x ...

  9. [JZOJ5818] 【NOIP提高A组模拟2018.8.15】 做运动

    Description 一天,Y 君在测量体重的时候惊讶的发现,由于常年坐在电脑前认真学习,她的体重有了突 飞猛进的增长. 幸好 Y 君现在退役了,她有大量的时间来做运动,她决定每天从教学楼跑到食堂来 ...

  10. 【NOIP提高A组模拟2018.8.14】 区间

    区间加:差分数组修改 O(n)扫描,负数位置单调不减 #include<iostream> #include<cstring> #include<cstdio> # ...

随机推荐

  1. golang 中 sync.Mutex 的实现

    mutex 的实现思想 mutex 主要有两个 method: Lock() 和 Unlock() Lock() 可以通过一个 CAS 操作来实现 func (m *Mutex) Lock() { f ...

  2. 模拟FCFS调度算法(先来先服务)

    文章目录 一.FCFS的介绍 二.代码演示 三.代码分析 1.使用节点模拟进程 2.SimulateFCFS(核心模拟FCFS类) 3.创建一个节点为n的队列(模拟就绪队列) 4.核心计算分析 5.输 ...

  3. mysql server_id的用途(主从等结构中)

    前言 我们都知道MySQL用server-id来唯一的标识某个数据库实例,并在链式或双主复制结构中用它来避免sql语句的无限循环.5.7需要同时设置server_id参数,8.0开始server_id ...

  4. java实现MD5文件加密

    package me.zhengjie.modules.logdump.util; import java.io.FileInputStream; import java.io.IOException ...

  5. Prometheus TSDB存储原理

    Prometheus 包含一个存储在本地磁盘的时间序列数据库,同时也支持与远程存储系统集成,比如grafana cloud 提供的免费云存储API,只需将remote_write接口信息填写在Prom ...

  6. 深度剖析text-align家族

    大家好,我是半夏,一个刚刚开始写文的沙雕程序员.如果喜欢我的文章,可以关注 点赞 加我微信:frontendpicker,一起学习交流前端,成为更优秀的工程师-关注公众号:搞前端的半夏,了解更多前端知 ...

  7. mmdetection获取最高map的epoch

    自动从训练结果中获取最高的mAP所对应的epoch. <code>import json import os ''' :param work_dir 训练结果目录 :return 最好的m ...

  8. [linux tips] puppet client ssl 证书过期

    问题: [root@control-01 .ssh]# puppet agent -tv Warning: Unable to fetch my node definition, but the ag ...

  9. Oracle 存储过程使用总结

    参考 https://blog.csdn.net/weixin_41968788/article/details/83659164/ 创建 注意:一定不要漏掉了语句末尾的分号 DBMS_OUTPUT. ...

  10. screen使用小结

    目录 安装 shell-screen-window关系 常用参数 快捷键 离开当前screen 打开一个新的窗口 查看窗口列表 窗口的快速切换 回到行首 关闭窗口 关闭所有窗口 关闭screen 删除 ...