poj3016
题解
求n编的poj3666
然后dp
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,M=;
int num[N],rt[N],size[N],T,tot,k,val[N],l[N],r[N],a[N],b[N],dist[N];
int c[N][],dp[N][],n,m,cost[M][M],cost1[M][M],cost2[M][M];
int merge(int x,int y)
{
if (!x||!y)return x+y;
if (val[x]<val[y])swap(x,y);
c[x][]=merge(c[x][],y);
size[x]=size[c[x][]]+size[c[x][]]+;
if (dist[c[x][]]<dist[c[x][]])swap(c[x][],c[x][]);
dist[x]=dist[c[x][]]+;
return x;
}
void pop(int &x){x=merge(c[x][],c[x][]);}
int newnode(int x)
{
size[++tot]=;
val[tot]=x;
c[tot][]=c[tot][]=dist[tot]=;
return tot;
}
void makecost1()
{
int res=,cnt=;
for (int j=;j<=n;j++)
{
tot=res=cnt=;
for (int i=j;i<=n;i++)
{
rt[++cnt]=newnode(b[i]);
l[cnt]=r[cnt]=i;num[cnt]=;
while (cnt>&&val[rt[cnt-]]>val[rt[cnt]])
{
cnt--;
if (num[cnt+]&)res+=(val[rt[cnt]]-val[rt[cnt+]]);
num[cnt]+=num[cnt+];
rt[cnt]=merge(rt[cnt],rt[cnt+]);
r[cnt]=r[cnt+];
while (size[rt[cnt]]*>r[cnt]-l[cnt]+)pop(rt[cnt]);
}
cost1[j][i]=res;
}
}
}
void makecost2()
{
int res=,cnt=;
for (int j=;j<=n;j++)
{
tot=res=cnt=;
for (int i=j;i<=n;i++)
{
rt[++cnt]=newnode(b[i]);
l[cnt]=r[cnt]=i;num[cnt]=;
while (cnt>&&val[rt[cnt-]]>val[rt[cnt]])
{
cnt--;
if (num[cnt+]&)res+=(val[rt[cnt]]-val[rt[cnt+]]);
num[cnt]+=num[cnt+];
rt[cnt]=merge(rt[cnt],rt[cnt+]);
r[cnt]=r[cnt+];
while (size[rt[cnt]]*>r[cnt]-l[cnt]+)pop(rt[cnt]);
}
cost2[j][i]=res;
}
}
}
void doit()
{
for (int i=;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i]-i;
makecost1();
for (int i=;i<=n;i++)b[i]=-a[i]-i;
makecost2();
memset(dp,0x3f,sizeof dp);
dp[][]=;
for (int i=;i<=n;i++)
for (int j=i;j<=n;j++)cost[i][j]=min(cost1[i][j],cost2[i][j]);
for (int i=;i<=n;i++)
for (int j=;j<=k&&j<=i;j++)
for (int p=j-;p<i;p++)
dp[i][j]=min(dp[i][j],dp[p][j-]+cost[p+][i]);
printf("%d\n",dp[n][k]);
}
int main()
{
while (~scanf("%d%d",&n,&k),n|k)doit();
}
poj3016的更多相关文章
- 【poj3016】 K-Monotonic
http://poj.org/problem?id=3016 (题目链接) 题意 给出一个数列,将一个数${a_i}$更改为${b_i}$的代价为${|a_i-b_i|}$.求将数列改为不递减的最小代 ...
- ACM训练计划step 2 [非原创]
(Step2-500题)POJ训练计划+SGU 经过Step1-500题训练,接下来可以开始Step2-500题,包括POJ训练计划的298题和SGU前两章200题.需要1-1年半时间继续提高解决问题 ...
- POJ训练计划
POJ训练计划 Step1-500题 UVaOJ+算法竞赛入门经典+挑战编程+USACO 请见:http://acm.sdut.edu.cn/bbs/read.php?tid=5321 一.POJ训练 ...
随机推荐
- python 的 ord()、 chr()、 unichr() 函数
一. ord() 函数描述ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参数,返 ...
- Java基础方法
1:读取resource下面的文件 ClassPathResource cpr = new ClassPathResource("./MyBatisXmlFile"); File ...
- 朴素贝叶斯算法原理及Spark MLlib实例(Scala/Java/Python)
朴素贝叶斯 算法介绍: 朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法. 朴素贝叶斯的思想基础是这样的:对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,在没有其它可用信息下,我 ...
- HDU5023:A Corrupt Mayor's Performance Art(线段树区域更新+二进制)
http://acm.hdu.edu.cn/showproblem.php?pid=5023 Problem Description Corrupt governors always find way ...
- 常微分方程初值问题:单步方法 [MATLAB]
#先上代码后补笔记# #可以直接复制粘贴调用的MATLAB函数代码!# 1. 朗格-库塔(Runge-Kutta)方法族 目前只实现了四阶Runge-Kutta方法. function [ YMat ...
- EF Code First 学习笔记:表映射(转)
多个实体映射到一张表 Code First允许将多个实体映射到同一张表上,实体必须遵循如下规则: 实体必须是一对一关系 实体必须共享一个公共键 观察下面两个实体: public class Per ...
- ng-深度学习-课程笔记-10: 机器学习策略2(Week2)
1 误差分析( Carrying out error analysis ) 假设你训练了一个猫的二分类模型,在开发集上的错误率是10%,你想分析这10%的错误率来自哪里,怎么做呢? 先把这些错分的图片 ...
- Java实现动态规划法求解0/1背包问题
摘要: 使用动态规划法求解0/1背包问题. 难度: 初级 0/1背包问题的动态规划法求解,前人之述备矣,这里所做的工作,不过是自己根据理解实现了一遍,主要目的还是锻炼思维和编程能力,同时,也是为了增进 ...
- ArrayBuffer:类型化数组
类型化数组是JavaScript操作二进制数据的一个接口. 这要从WebGL项目的诞生说起,所谓WebGL,就是指浏览器与显卡之间的通信接口,为了满足JavaScript与显卡之间大量的.实时的数据交 ...
- ELF文件分析
(1)文件ELF.c (2)编译: gcc -c ELF_1.c -o ELF_1.o (3)显示文件类型: (4)查看大小: (5)转换为16进制 (6)显示各段信息 (7)分析