题目: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 ;
}

最新文章

  1. HDU2444-The Accomodation of Students-判断是否为二分图+ISAP
  2. HTML5之Canvas绘图实例——曲线图
  3. php-PHP试题
  4. Robot Framework自动化测试环境准备(一)
  5. stl学习之字符串
  6. 【JavaScript的五种基本数据类型及转换】
  7. mongodb 配置均衡器的运行窗口
  8. java中的Collection集合类
  9. 在java程序中实现发送邮件的功能
  10. Animate与transform的使用
  11. 2015-11-06 ajax
  12. TensorFlow从入门到理解(一):搭建开发环境【基于Ubuntu18.04】
  13. Windows PowerShell 入門(9)-エラー編
  14. Navicat 提示 Access violation at address ***(如004ECCF4) in module ‘navicat.exe’. Read of address ***(如00000048)
  15. 绑定属性 - v-bind
  16. jQuery基础语法
  17. Spring static 静态属性注入
  18. [Canvas]New Running Dog
  19. javascript刷新页面代码
  20. Sentinel配置及部署

热门文章

  1. [Go]条件语句
  2. android去除标题栏和状态栏(全屏)
  3. 【POJ3294】Life Forms(后缀数组,二分)
  4. 【git】git分支的合并
  5. poj1330+hdu2586 LCA离线算法
  6. iOS React Native 环境的搭建
  7. Javaee的霸主之spring系列
  8. Maven新建webapp项目报错Could not resolve artifact org.apache.maven.archetypes:maven-archetype-webapp:pom:RELEASE
  9. 转:String数组初始化
  10. Java多线程导致的的一个事物性问题