区间 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. Mybatis个人笔记

    Mybatis 简介 官网地址:mybatis – MyBatis 3 | 简介 MyBatis 是一款优秀的持久层框架,它支持自定义 SQL.存储过程以及高级映射.MyBatis 免除了几乎所有的 ...

  2. 【面试普通人VS高手系列】Fail-safe机制与Fail-fast机制分别有什么作用

    前段时间一个小伙伴去面试,遇到这样一个问题. "Fail-safe机制与Fail-fast机制分别有什么作用" 他说他听到这个问题的时候,脑子里满脸问号.那么今天我们来看一下,关于 ...

  3. k8s和Docker

    Docker是一个开源的应用容器引擎k8s是一个开源的容器集群管理系统这里我尽量用比较浅显的方式来说明k8s系统 一.k8s是如何管理的节点的呢:1.k8s 分master和node 2.master ...

  4. Vuecli版本调整

    1.当前版本号查看 1.Windows+R打开命令提示符2.输入cmd3.vue --version或者vue -V(大写V) 2.版本操作 安装指定版本 情况一:目前处于3.0及以上 版本查看和卸载 ...

  5. Codeforces Round #719 (Div. 3) C. Not Adjacent Matrix

    地址 Problem - C - Codeforces 题意 每个格子,该格子和相邻的格子的值不能相同 题解 思维题, 先从1~n输出奇数,再输出偶数 代码 #include <iostream ...

  6. 前端vue之属性指令、style和class、条件渲染、列表渲染、事件处理、数据双向绑定、表单控制、v-model进阶

    今日内容概要 属性指令 style和class 条件渲染 列表渲染 事件处理 数据的双向绑定 v-model进阶 购物车案例 内容详细 1.属性指令 <!DOCTYPE html> < ...

  7. Ubuntu 百度飞桨和 CUDA 的安装

    Ubuntu 百度飞桨 和 CUDA 的安装 1.简介 本文主要是 Ubuntu 百度飞桨 和 CUDA 的安装 系统:Ubuntu 20.04 百度飞桨:2.2 为例 2.百度飞桨安装 访问百度飞桨 ...

  8. 联邦平均算法(Federated Averaging Algorithm,FedAvg)

    设一共有\(K\)个客户机, 中心服务器初始化模型参数,执行若干轮(round),每轮选取至少1个至多\(K\)个客户机参与训练,接下来每个被选中的客户机同时在自己的本地根据服务器下发的本轮(\(t\ ...

  9. Mozi.HttpEmbedded嵌入式Web服务器

    Mozi.HttpEmbedded 嵌入式Web服务器 项目介绍 Mozi.HttpEmbedded是一个基于.Net构建的嵌入式Web服务器,为.Net App提供web服务功能. 嵌入式的目标不是 ...

  10. 如何设计一个良好的API接口?

    沟通创造价值,分享带来快乐.这里是程序员阅读时间,每天和你分享读书心得,欢迎您每天和我一起精进.今天和大家一起讨论的话题是如何设计一个良好的API接口? 作者:梁桂钊 解读:张飞洪 挑战 API是软件 ...