E - Partition Game

题目描述

定义一个序列 ttt 的 costcostcost 为 cost(t)=∑x∈set(t)last(x)−first(x)cost(t)=\sum_{x\in set(t)}last(x)-first(x)cost(t)=∑x∈set(t)​last(x)−first(x) 。

其中 set(t)set(t)set(t) 为 ttt 中所有元素组成的不重集合, last(x)last(x)last(x) 表示元素 xxx 出现的最后一个位置, first(x)first(x)first(x) 表示元素 xxx 出现的第一个位置。

给定序列 aaa ,把 aaa 分成恰好 kkk 段,求每一段的 costcostcost 值相加的和最小是多少。

数据范围与提示

1≤n≤35000,1≤k≤min⁡(n,100),1≤ai≤n1\le n\le 35000,1\le k\le \min(n,100),1\le a_i\le n1≤n≤35000,1≤k≤min(n,100),1≤ai​≤n 。

思路

这题没什么性质,就是一个纯的数据结构优化 DP\text{DP}DP 的题。

设 dp[i][j]dp[i][j]dp[i][j] 表示前 iii 个数划分成 jjj 段时这 jjj 段的 costcostcost 相加的最小值,显然有
dp[i][j]=min⁡(dp[k][j−1]+cost(a[k+1,i])),k∈[0,i−1]dp[i][j]=\min(dp[k][j-1]+cost(a[k+1,i])),k\in [0,i-1] dp[i][j]=min(dp[k][j−1]+cost(a[k+1,i])),k∈[0,i−1]
其中 a[i,j]a[i,j]a[i,j] 表示序列 aaa 中第 iii 个元素到第 jjj 个元素组成的子段。

我们可以对于每个 jjj ,用一棵线段树维护 dp[k][j]+cost(a[k+1,i])dp[k][j]+cost(a[k+1,i])dp[k][j]+cost(a[k+1,i]) 的最小值,由于 last(x)−first(x)last(x)-first(x)last(x)−first(x) 就等于每相邻两个 xxx 的距离相加,所以每次只需要把新出现的一对相邻 xxx 加进对应的 costcostcost 里面即可。

具体地,设 bf(i)bf(i)bf(i) 表示 iii 左边第一个与它相同的元素的位置,那么我们需要利用数据结构把每一个 dp[k][j]+cost(a[k+1,i]),k∈[0,bf[i]−1]dp[k][j]+cost(a[k+1,i]),k\in [0,bf[i]-1]dp[k][j]+cost(a[k+1,i]),k∈[0,bf[i]−1] 都加上 i−bf[i]i-bf[i]i−bf[i] 。

时间复杂度 O(nklog⁡n)O(nk\log n)O(nklogn) ,你可能需要一些常数比较小的数据结构 (比如zkw) 。

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#define ll long long
#define MAXN 35005
#define uns unsigned
//#define int ll
using namespace std;
inline ll read(){ll x=0;bool f=1;char s=getchar();while((s<'0'||s>'9')&&s>0){if(s=='-')f^=1;s=getchar();}while(s>='0'&&s<='9')x=(x<<1)+(x<<3)+s-'0',s=getchar();return f?x:-x;
}
int n,k,a[MAXN],bf[MAXN],las[MAXN],p;
ll f[105][MAXN*3],lz[105][MAXN*3],dp[MAXN][105];
inline void add(int K,int l,int r,ll ad){for(l=p+l-1,r=p+r+1;l^1^r;){if(~l&1)f[K][l^1]+=ad,lz[K][l^1]+=ad;if(r&1)f[K][r^1]+=ad,lz[K][r^1]+=ad;l>>=1,r>>=1;f[K][l]=min(f[K][l<<1],f[K][l<<1|1])+lz[K][l];f[K][r]=min(f[K][r<<1],f[K][r<<1|1])+lz[K][r];}for(l>>=1;l;l>>=1)f[K][l]=min(f[K][l<<1],f[K][l<<1|1])+lz[K][l];
}
inline void change(int K,int x,ll d){for(f[K][p+x]=d,x=(p+x)>>1;x;x>>=1)f[K][x]=min(f[K][x<<1],f[K][x<<1|1])+lz[K][x];
}
signed main()
{n=read(),k=read();for(int i=1;i<=n;i++)a[i]=read();for(int i=1;i<=n;i++)bf[i]=las[a[i]],las[a[i]]=i;for(p=1;p<n+3;p<<=1);memset(f,0x3f,sizeof(f));change(0,1,0);for(int i=1;i<=n;i++){if(bf[i]>0)for(int j=0;j<=k;j++)add(j,1,bf[i],i-bf[i]);for(int j=1;j<=min(i,k);j++)dp[i][j]=f[j-1][1],change(j,i+1,dp[i][j]);}printf("%lld\n",dp[n][k]);return 0;
}

CF1527E Partition Game——DP优化相关推荐

  1. hdu3585 二分最大团(dp优化)

    题意       给你一些点( <= 50),让你找到k个点,使得他们之间的最小距离最大. 思路:       求最小的最大,我们可以直接二分去枚举距离,但是要注意,不要去二分double找距离 ...

  2. hdu1505 暴力或dp优化

    题意:        给你一个矩阵,让你在里面找到一个最大的f矩阵.. 思路:       三种方法ac这到题目;  方法(1) 以宽为主,暴力    开一个数组sum[i][j],记录当前这个位置的 ...

  3. [DP优化之平行四边形不等式]例题

    目录 概述 例题 Post Office 题目描述 解题思路 总结 Monkey Party 题目链接 解题思路 总结 评述 概述 首先说明一点,这种方法不是什么题都可以用的,我们要判断DP的情况,看 ...

  4. [BZOJ1499][NOI2005][DP+优化]瑰丽华尔兹

    [Problem Description] 你跳过华尔兹吗?当音乐响起,当你随着旋律滑动舞步,是不是有一种漫步仙境的惬意?众所周知,跳华尔兹时,最重要的是有好的音乐.但是很少有几个人知道,世界上最伟大 ...

  5. C++剑指offer:解题报告之DP优化学习记 (二) ——浅论DP斜率优化 (Print Article 【HDU - 3507】 )

    链接:https://share.weiyun.com/5LzbzAc 目录 前言 斜率优化前期准备 1.从状态转移方程出发 2.推理状态转移方程 对结论的进一步推导 干货!综合结论 判断斜率大小的方 ...

  6. Coins(多重背包方案可行性dp + 优化)

    Coins 题目 给出硬币面额及每种硬币的个数,求从1到m能凑出面额的个数. 思路 1.朴素的多重背包 题面给出的很明显的多重背包,定义dp为考虑前i种硬币,能凑出j元的方案可行性,可以得到第一版代码 ...

  7. CodeForces - 1527E Partition Game(dp+线段树)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的数列,现在需要将其划分成 kkk 段,使得贡献和最小 对于每段区间 [l,r][l,r][l,r] 的贡献为,其中每个数字,其最后一次出现的位置 ...

  8. 01背包问题dp优化

    背包容量m给定,选择n件物品,求放入背包的最大价值. 其中,物品只能选择一次,要么放,要么不放. 朴素解法 经典的DP问题 状态:f[i][j]f[i][j]f[i][j]表示选择前iii个物品,背包 ...

  9. 【DP优化】【P1430】序列取数

    传送门 Description 给定一个长为n的整数序列,由A和B轮流取数(A先取).每个人可从序列的左端或右端取若干个数(至少一个),但不能两端都取.所有数都被取走后,两人分别统计所取数的和作为各自 ...

最新文章

  1. 2021 IDEA大会开启AI思想盛宴,用“创业精神”做科研
  2. Log4Net五步走
  3. 汇编和python-PyAsm-在python中嵌入汇编 | 学步园
  4. SpringMVC教程--json使用详解
  5. 【Zookeeper】源码分析之持久化(三)之FileTxnSnapLog
  6. mysql 慢日志报警_一则MySQL慢日志监控误报的问题分析
  7. 云原生应用架构转型不好做?阿里云这个平台让你一步到位!
  8. 面试官 | 这位连单点登录都不知道,让他回家等通知去吧
  9. 列表(添加、修改、查、删除)
  10. Gradient Boosting and GBDT
  11. 红帽变蓝帽对Ceph有何影响?
  12. Java MD5加密工具包
  13. Memcached缓存
  14. 蓝牙室内定位技术,蓝牙定位信标应用场景及分析
  15. matlab笔记 与excel表格的数据交互—xlsread和xlswrite函数
  16. Date的after和before方法
  17. Codeblocks 深色主题背景设置、美化界面
  18. iOS10新特性——————陈Hong鑫
  19. 抓取淘宝司法拍卖数据
  20. 计算机控制篮球,【精品课程设计】计算机控制技术弱电课程之篮球比赛计时计分器doc.doc...

热门文章

  1. 深入浅出理解类和对象
  2. UnityStandardAsset工程、源码分析_4_赛车游戏[玩家控制]_摄像机控制
  3. 20210326TCPandUDP
  4. Golang高性能日志库zap + lumberjack 日志切割组件详解
  5. 提车二月记--小鹏P7
  6. 不起眼的浏览器_借助不起眼的独立游戏包,以低廉的价格获得令人敬畏的游戏...
  7. DVD PullDown 详解
  8. QT自制秒表计时器、可获取电脑时间
  9. Untiy 游戏存档PlayerPrefs
  10. 3D MAX入门训练(1)放样制作胡萝卜