题解

求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的更多相关文章

  1. 【poj3016】 K-Monotonic

    http://poj.org/problem?id=3016 (题目链接) 题意 给出一个数列,将一个数${a_i}$更改为${b_i}$的代价为${|a_i-b_i|}$.求将数列改为不递减的最小代 ...

  2. ACM训练计划step 2 [非原创]

    (Step2-500题)POJ训练计划+SGU 经过Step1-500题训练,接下来可以开始Step2-500题,包括POJ训练计划的298题和SGU前两章200题.需要1-1年半时间继续提高解决问题 ...

  3. POJ训练计划

    POJ训练计划 Step1-500题 UVaOJ+算法竞赛入门经典+挑战编程+USACO 请见:http://acm.sdut.edu.cn/bbs/read.php?tid=5321 一.POJ训练 ...

随机推荐

  1. PHP面向对象详解:继承、封装与多态

    首先,在解释面向对象之前先解释下什么是面向对象? [面向对象]1.什么是类? 具有相同属性(特征)和方法(行为)的一系列个体的集合,类是一个抽象的概念2.什么是对象?从类中拿到的具有具体属性值得个体, ...

  2. Python开发【笔记】:“~” 按位取反运计算方法

    按位取反: 要弄懂这个运算符的计算方法,首先必须明白二进制数在内存中的存放形式,二进制数在内存中是以补码的形式存放的 原码 原码(true form)是一种计算机中对数字的二进制定点表示方法.原码表示 ...

  3. cocos2d 特效

    一.特效概念 特效是让精灵(CCSprite)执行某种特殊的效果.其实,特效也是一种动画! 但是,为什么要把特效与动画区分呢?因为,特效是基于网格属性来进行的. 如何区分动画与特效?简单的将,当使用到 ...

  4. mapxtreme java学习之路(1)——.dwg转.tab再转.gst详细教程

    [背景] 因为项目的需要,需要在java web 项目中使用到地图,厂家提供的是dwg格式的地图,而我们采用的是mapxtreme java技术,所以先要把dwg格式的地图转成mapxtreme ja ...

  5. mysql 数据操作 单表查询 group by 分组 目录

    mysql 数据操作 单表查询 group by 介绍 mysql 数据操作 单表查询 group by 聚合函数 mysql 数据操作 单表查询 group by 聚合函数 没有group by情况 ...

  6. mysql 数据操作 单表查询 查询排序: order by

    如果不指定排序 默认是按照id字段 从小到大排序的  升序 mysql> select * from employee; +----+------------+--------+-----+-- ...

  7. 三个小时学会wordpress模板制作

    最近接了一个项目需要用wordpress建站,版面相对简单,ytkah就琢磨着自己来设计wordpress模板,首页栏目页文章页(很多网站无外乎就这些页面),其中栏目页和首页又很像,都是调用文章列表. ...

  8. 有关ros::spin()和ros::spinonce()若干感受

    ros::spinonce()一般与loop_rate.sleep()同时出现,用来控制处理回调函数的频率,并且没有消息就收来时,就会程序堵塞,不会占用CPU资源. ros::spin(),用于回调函 ...

  9. chrome 关闭安全模式

    chrome.exe --disable-web-security --user-data-dir

  10. C语言的 32个关键之和9个控制语言之关键字

    auto   break  case  char  const  continue  default  do double  else  enum  extern  float for  goto  ...