洛谷P2943 清理——DP
2024-08-30 17:49:46
题目:https://www.luogu.org/problemnew/show/P2943
一眼看去就有个 n^2 的做法:f[i] = min{ f[j] + num( i - j ) * num( i - j ) } , 1 <= j < i;
但仔细想想这个做法,发现那个num数组很不好处理;
也就是我们需要关注一个区间内食品的种类数;
不妨根据这个来调整做法,直接枚举种类数;
这样做的好处是可以进行转移,因为从 i 到 i+1 会带来一个种类数量的改变;
由此受到启发,设数组 pos[j] 为种类数是 j 时可到达的最远节点(越远越优);
再对每个点记录一下前驱后继以便于进行种类数是否增加的判断;
cnt数组记录 pos[j] 到 i 这一段(实际的)种类数,就可以转移了。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const maxn=;
int n,m,f[maxn],pos[maxn],cnt[maxn],pre[maxn],nxt[maxn],lst[maxn],a[maxn];
int main()
{
scanf("%d%d",&n,&m);
for(int i=,x;i<=n;i++)
{
scanf("%d",&x);a[i]=x;
pre[i]=lst[x];
nxt[lst[x]]=i;
lst[x]=i;
nxt[i]=n+;
}
for(int i=;i*i<=n;i++)pos[i]=;//!
memset(f,0x3f,sizeof f);
f[]=;
for(int i=;i<=n;i++)
for(int j=;j*j<=n;j++)
{
if(pre[i]<pos[j])cnt[j]++;
if(cnt[j]>j)
{
cnt[j]--;
while(nxt[pos[j]]<=i)pos[j]++;
pos[j]++;
}
f[i]=min(f[i],f[pos[j]-]+j*j);
}
printf("%d",f[n]);
return ;
}
最新文章
- HDU2444-The Accomodation of Students-判断是否为二分图+ISAP
- HTML5之Canvas绘图实例——曲线图
- php-PHP试题
- Robot Framework自动化测试环境准备(一)
- stl学习之字符串
- 【JavaScript的五种基本数据类型及转换】
- mongodb 配置均衡器的运行窗口
- java中的Collection集合类
- 在java程序中实现发送邮件的功能
- Animate与transform的使用
- 2015-11-06 ajax
- TensorFlow从入门到理解(一):搭建开发环境【基于Ubuntu18.04】
- Windows PowerShell 入門(9)-エラー編
- Navicat 提示 Access violation at address ***(如004ECCF4) in module ‘navicat.exe’. Read of address ***(如00000048)
- 绑定属性 - v-bind
- jQuery基础语法
- Spring static 静态属性注入
- [Canvas]New Running Dog
- javascript刷新页面代码
- Sentinel配置及部署
热门文章
- [Go]条件语句
- android去除标题栏和状态栏(全屏)
- 【POJ3294】Life Forms(后缀数组,二分)
- 【git】git分支的合并
- poj1330+hdu2586 LCA离线算法
- iOS React Native 环境的搭建
- Javaee的霸主之spring系列
- Maven新建webapp项目报错Could not resolve artifact org.apache.maven.archetypes:maven-archetype-webapp:pom:RELEASE
- 转:String数组初始化
- Java多线程导致的的一个事物性问题