http://acm.hdu.edu.cn/showproblem.php?pid=5009

题目要求对空序列染成目标颜色序列,对一段序列染色的成本是不同颜色数的平方。

这题我们显然会首先想到用DP去解决,dp[i] = min( dp[i] , dp[j] + cost(i , j) )。但是枚举ij的复杂的高达n^2,不能接受,我们就考虑去优化它。

首先比较容易想到的是,去除连续重复元素,可以把它们当作同一个点处理。

此外在遍历j的过程中如果当前序列颜色不同的数量平方大于当前dp[i],显然已经没有一并涂色以及继续扩充序列的必要了(随着序列数的增长,不同颜色的数量是单调递增的,必然在之后不会出现小于dp[i]的情况。

但是这样并不能把复杂的降低至sqrt(n)*n,因为我们枚举的子序列会有重复元素,所以并不是每次j的变化都会来带不同颜色数的增长,比如24242424这种。那么我们考虑这种情况该如何优化,我们先换一个比较容易理解的例子9871341,当我们的i指向最后一个1的时候,我们的j开始向前遍历,当遍历到上一个i的时候,其实我们已经知道,这个i我们把它包含进去是没有成本的(因为之前已经有1了,并不会使不同颜色的数增加)所以我们应该不假思索地加入这个数。但是计算机是很蠢的,它每次依旧会遍历到它,别看这遍历一个单位很快,像24242424这种就会导致计算机大量重复地枚举了。为此我们模拟一个双向链表,在枚举i地过程中,我们维护前缀序列地链表全都是不同的元素,这个实现起来其实并不难,因为i每次增长最多会增加一个重复元素,相应的我们也只需要去除一个重复元素(即上一次出现当前值的那个位置)。然后在遍历j的时候只需要遍历链表就好了。这样我们保证j遍历过程中每次都能增加一个不同颜色,复杂的自然降低到n*sqrt(n)了。

#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <cstdio>
#define LL int
using namespace std;
const int N=;
const LL inf=1e8+;
LL arr[N];
LL dp[N];
int pre[N];
int nex[N];
int main()
{
cin.sync_with_stdio(false);
int n;
while(cin>>n)
{
int p=;
for(int i=; i<n; i++)
{
int c;
//c=_read();
cin>>c;
if(i==||arr[p]==c)
arr[p]=c;
else
arr[++p]=c;
}
map<LL,int> unq;
int rk=;
for(int i=; i<=p; i++)
{
map<LL,int>::iterator it=unq.find(arr[i]);
if(it!=unq.end())
arr[i]=it->second;
else
{
unq[arr[i]]=rk;
arr[i]=rk;
rk++;
}
pre[i]=i-;
nex[i]=i+;
}
dp[p+]=;
map<LL,int> v;
for(int i=p; i>=; i--)
{
LL ans=inf;
if(v.find(arr[i])==v.end())
v[arr[i]]=i;
else
{
int ix=v[arr[i]];
nex[pre[ix]]=nex[ix];
pre[nex[ix]]=pre[ix];
v[arr[i]]=i;
}
int rx;
int cnt=;
for(int j=i; j!=p+; j=nex[j])
{
//cout<<j<<endl;
cnt++;
LL p2=cnt*cnt;
if(p2>ans)
break;
if(p2+dp[nex[j]]<ans)
{
ans=p2+dp[nex[j]];
rx=j;
}
//ans=min(ans,(LL)(xx+dp[j+1]));
//cout<<ans<<' '<<s.size()<<' '<<dp[j+1]<<endl;
}
dp[i]=ans;
//cout<<dp[i]<<' '<<i<<' '<<rx<<endl;
}
//printf("%d\n",dp[0]);
cout<<dp[]<<endl;
}
return ;
}

hdu-5009 Paint Pearls DP+双向链表 with Map实现去重优化的更多相关文章

  1. HDU - 5009 Paint Pearls(dp+优化双向链表)

    Problem Description Lee has a string of n pearls. In the beginning, all the pearls have no color. He ...

  2. HDU 5009 Paint Pearls 双向链表优化DP

    Paint Pearls Problem Description   Lee has a string of n pearls. In the beginning, all the pearls ha ...

  3. HDU 5009 Paint Pearls(西安网络赛C题) dp+离散化+优化

    转自:http://blog.csdn.net/accelerator_/article/details/39271751 吐血ac... 11668627 2014-09-16 22:15:24 A ...

  4. HDU 5009 Paint Pearls (动态规划)

    Paint Pearls Problem Description Lee has a string of n pearls. In the beginning, all the pearls have ...

  5. hdu 5009 Paint Pearls

    首先把具有相同颜色的点缩成一个点,即数据离散化. 然后使用dp[i]表示涂满前i个点的最小代价.对于第i+1个点,有两种情况: 1)自己单独涂,即dp[i+1] = dp[i] + 1 2)从第k个节 ...

  6. HDU-5009 Paint Pearls 动态规划 双向链表

    题目链接:https://cn.vjudge.net/problem/HDU-5009 题意 给一串序列,可以任意分割多次序列,每次分割的代价是被分割区间中的数字种数. 求分割区间的最小代价.n< ...

  7. HDOJ 5009 Paint Pearls

    Dicripntion Lee has a string of n pearls. In the beginning, all the pearls have no color. He plans t ...

  8. AC日记——Paint Pearls hdu 5009

    Paint Pearls 思路: 离散化+dp+剪枝: dp是个n方的做法: 重要就在剪枝: 如果一个长度为n的区间,有大于根号n种颜色,还不如一个一个涂: 来,上代码: #include <c ...

  9. hdu5009 Paint Pearls (DP+模拟链表)

    http://acm.hdu.edu.cn/showproblem.php?pid=5009 2014网络赛 西安 比较难的题 Paint Pearls Time Limit: 4000/2000 M ...

随机推荐

  1. 【ArcGIS for Server】制作并发布GP服务--缓冲分析为例

    https://www.cnblogs.com/d2ee/p/3641279.html https://www.jianshu.com/p/5331fa708fe5 https://www.cnblo ...

  2. Spring MVC原理及配置详解

    Spring MVC概述: Spring MVC是Spring提供的一个强大而灵活的web框架.借助于注解,Spring MVC提供了几乎是POJO的开发模式,使得控制器的开发和测试更加简单.这些控制 ...

  3. 7.1-uC/OS-III中断管理

    在 uC/OS 系统中,中断相当于一个优先级最高的任务.中断一般用于处理比较紧急的事件, 而且只做简单处理,例如标记该事件,带退出中断后再做详细处理.在使用 uC/OS系统时, 一般建议使用信号量. ...

  4. Mysql数据库配置参数详解大全

    名称 是否需要重启 值 允许值 描述 auto_increment_increment 否 1 1-65,535 auto_increment_increment和auto_increment_off ...

  5. 20190422 T-SQL 触发器

    -- 1 数据库服务 -- 2 触发器 CREATE TRIGGER no_inserton xsAFTER INSERT ASBEGIN RAISERROR('XS不让插入数据',1,1); ROL ...

  6. freeswitch报错

    1.         2010-10-26 11:01:58.448513 [ERR] sofia_reg.c:816 Can not do authorization without a compl ...

  7. jQuery-form实现文件分步上传

    分步上传:当你需要提交两个及以上的文件,在一个文件成功后再提交另一个文件,并且最后需要提交所有文件的地址组成的数据 HTML: <form id="uploadVideoForm&qu ...

  8. 移动端项目在ios上输入框聚焦难解决方案

    由于引入fastclick导致ios端input.textarea输入框难以点击聚焦,解决方案如下: 找到项目中的fastclick依赖或在main.js中改写fastclick的focus实现.

  9. IP通信基础学习第三周(上)

    TCP的连接情况有:同时打开,同时关闭,拒绝连接,异常终止连接. TCP流量控制的折中方法是滑动窗口协议,且TCP标准强烈不赞成发送窗口沿向后缩回. 在滑动窗口中,当A发送了11个字节的数据时,P3- ...

  10. dotnet core命令

    dotnet run -----运行程序 dotnet publish -r centos-x64  -----发布程序 mkdri 文件名--->cd 文件名--->dotnet new ...