@spoj - ADAMOLD@ Ada and Mold
@description@
给定一个长度为 N 的序列 A,将其划分成 K + 1 段,划分的代价为每一段中两两元素的异或之和。
求最小划分代价。
1 ≤ K < N ≤ 5000,0 ≤ Ai ≤ 10^9。
@solution@
一个朴素的 dp:定义 dp[i][j] 表示将前 j 个数划分成 i 段的最小代价。
转移时枚举 k <= j,用 dp[i-1][k-1] + cost(k, j) 转移到 dp[i][j]。
看了一会儿没什么优化的思路,那么考虑决策单调性。记 pnt[i][j] 表示 dp[i][j] 的最优决策点。
通过打表发现好像有 pnt[i][j-1] <= pnt[i][j] 与 pnt[i-1][j] <= pnt[i][j] 两重单调性存在。
感性理解起来好像两个都是对的。
前一个直接可以证,后面一个需要用平行四边形不等式的方法来分析。这里就不再详细阐述了。
因此有 pnt[i-1][j] <= pnt[i][j] <= pnt[i][j+1],通过从小到大枚举 i,从大到小枚举 j 的方法可以求出 pnt[i][j] 的范围,直接在这个范围内暴力找最优决策点即可。
时间复杂度?求 pnt[i][j] 需要扫描 pnt[i][j+1] - pnt[i-1][j] 个数,可以写成 (pnt[i][j+1] - pnt[i][j]) + (pnt[i][j] - pnt[i-1][j])。
对于每一个 i, j,将上式进行求和,最终结果为 ∑(pnt[i][n] + pnt[n][i])。
注意到 pnt[i][n], pnt[n][i] <= n,因此时间复杂度为 O(n^2)。
@accepted code@
#include <cstdio>
typedef long long ll;
const int MAXN = 5000;
const ll INF = (1LL<<60);
ll f[MAXN + 5], g[MAXN + 5];
int pnt[MAXN + 5], tmp[MAXN + 5];
ll c[MAXN + 5][MAXN + 5];
int A[MAXN + 5];
int main() {
int N, K; scanf("%d%d", &N, &K), K++;
for(int i=1;i<=N;i++) scanf("%d", &A[i]);
for(int i=1;i<=N;i++) {
ll s = 0;
for(int j=i-1;j>=1;j--) {
s += (A[i] ^ A[j]);
c[j][i] = c[j][i-1] + s;
}
}
for(int i=1;i<=N;i++) f[i] = INF, pnt[i] = 1;
for(int i=1;i<=K;i++) {
for(int j=1;j<=N;j++) g[j] = f[j], f[j] = INF, tmp[j] = pnt[j];
for(int j=N;j>=i;j--) {
int l = tmp[j], r = (j == N ? N : pnt[j+1]), m = l;
for(int k=l;k<=r&&k<=j;k++)
if( f[j] > g[k-1] + c[k][j] )
f[j] = g[k-1] + c[k][j], m = k;
pnt[j] = m;
}
}
printf("%lld\n", f[N]);
}
@details@
其实不详细阐述的原因是我自己还没有看懂平行四边形不等式优化。
@spoj - ADAMOLD@ Ada and Mold的更多相关文章
- SPOJ:Ada and Orange Tree (LCA+Bitset)
Ada the Ladybug lives near an orange tree. Instead of reading books, she investigates the oranges. T ...
- [SPOJ 30669] Ada and Trip
[题目链接] https://www.spoj.com/problems/ADATRIP/ [算法] 直接使用dijkstra堆优化算法即可 [代码] #include<bits/stdc++. ...
- SPOJ ADAFIELD Ada and Field(STL的使用:set,multiset,map的迭代器)题解
题意:n*m的方格,“0 x”表示x轴在x位置切一刀,“0 y”表示y轴在y位置切一刀,每次操作后输出当前面积最大矩形. 思路:用set分别储存x轴y轴分割的点,用multiset(可重复)储存x轴y ...
- SPOJ:Ada and Graft (set合并&优化)
As you might already know, Ada the Ladybug is a farmer. She grows a big fruit tree (with root in 0). ...
- BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 5217 Solved: 1233 ...
- SPOJ DQUERY D-query(主席树)
题目 Source http://www.spoj.com/problems/DQUERY/en/ Description Given a sequence of n numbers a1, a2, ...
- SPOJ GSS3 Can you answer these queries III[线段树]
SPOJ - GSS3 Can you answer these queries III Description You are given a sequence A of N (N <= 50 ...
- 【填坑向】spoj COT/bzoj2588 Count on a tree
这题是学主席树的时候就想写的,,, 但是当时没写(懒) 现在来填坑 = =日常调半天lca(考虑以后背板) 主席树还是蛮好写的,但是代码出现重复,不太好,导致调试的时候心里没底(虽然事实证明主席树部分 ...
- SPOJ bsubstr
题目大意:给你一个长度为n的字符串,求出所有不同长度的字符串出现的最大次数. n<=250000 如:abaaa 输出: 4 2 1 1 1 spoj上的时限卡的太严,必须使用O(N)的算法那才 ...
随机推荐
- Golang数据库操纵对IN语句的支持
一: 在实际的工程项目中,SQL通常使用预编译的形式进行执行操纵,可以有效的防止SQL注入的风险,提高编码的规范性.golang中使用sqlx进行sql查询的时候,在使用in语句在一个集合中查询的时候 ...
- CSS3属性transform详解【转载】
CSS3属性transform详解之(旋转:rotate,缩放:scale,倾斜:skew,移动:translate) 在CSS3中,可以利用transform功能来实现文字或图像的旋转.缩放.倾 ...
- PAT甲级——A1060 Are They Equal
If a machine can save only 3 significant digits, the float numbers 12300 and 12358.9 are considered ...
- Jmeter分布式测试过程中遇到的问题及摘抄前辈问题汇总
遇到的常见问题: 1.在Controller端上控制某台机器Run,提示"Bad call to remote host". 解决方法:检查被控制机器上的jmeter-server ...
- svn详解和使用
2 svn介绍 2.1 项目管理中的版本控制问题 通常软件开发由多人协作开发,如果对代码文件.配置文件.文档等没有进行版本控制,将会出现很多问题: > 备份多个版本,占用磁盘空间大> 解决 ...
- RandomRowFilter(3)
比较容易理解 用来随机抽取 RandomRowFilter:从名字上就可以看出其大概的用法,本过滤器的作用就是按照一定的几率(<=0会过滤掉所有的行,>=1会包含所有的行)来返回随机的结果 ...
- JVM学习-之对象的创建和内存分配
最近看JVM内存模型,看了很多文章,大都讲到JVM将内存区域划分分:Mehtod-Area(No heap) 方法区,Heap(堆)区,Program Counter Register(程序计数器), ...
- 解释性语言和非解释性语言,GIL锁
解释性语言:python写的代码就被称为程序,cpu硬件能运行二进制代码指令.demo.py需要经过python解释器编译才做才能执行. 非解释性语言:例如c语言程序,同样需要写代码.demo.c这个 ...
- pc端拖拽
var move=document.getElementsByClassName("page1_2")[0]; var startX=0; var startY=0; var x= ...
- 使用uni-app(Vue.js)创建运行微信小程序项目步骤
使用uni-app(Vue.js)开发微信小程序项目步骤 1. 新建一个uni-app项目 创建完成后的目录结构 2. 打开微信小程序开发工具端的端口调试功能 3. 运行创建的项目 效果