题解

求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. 原!上线遇到的问题, java序列化关键字transient 修饰的属性变成null了

    1.问题描述: 某个功能点,user对象 放入session,后再另外地方取出,结果某个字段没有了.再本地和测试环境都是ok的,但是线上环境就是不行. 后来看到这个user对象的那个属性是加了tran ...

  2. spring boot由浅入深(一)jdk安装

    1jdk说明 jdk是java提供了运行环境,简单的说就是给java语言制定了规则,并且提供了工具 jdk官网网站:http://www.oracle.com/technetwork/java/jav ...

  3. OOP理解

    https://www.cnblogs.com/xiaosongluffy/p/5072501.html OOP是面向对象编程,有几大基础特性.抽象,封装,继承,多态 1:抽象:将世界上的具体事物提取 ...

  4. [svc]堡垒机模型设计初步

    models from django.contrib.auth.models import AbstractUser from django.db import models # Create you ...

  5. [golang note] 网络编程 - RPC编程

    net包 • 官方文档 http://godoc.golangtc.com/pkg/net/ Package net provides a portable interface for network ...

  6. C++中的RAII介绍 资源管理

    摘要 RAII技术被认为是C++中管理资源的最佳方法,进一步引申,使用RAII技术也可以实现安全.简洁的状态管理,编写出优雅的异常安全的代码. 资源管理 RAII是C++的发明者Bjarne Stro ...

  7. Qt emit的使用

    1. 假设现在我定义了一个类A,现在想在A的一个函数void A::function1()当中的结尾处emit一个信号signal1(),然后利用这个信号触发另一个类B进行某项操作void B::fu ...

  8. 70. Climbing Stairs(动态规划 爬台阶,一次只能爬1,2两节)

    You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...

  9. 2017年浙江中医药大学程序设计竞赛 Solution

    训练地址 A: 树剖板子题 求最小值的时候要注意值是不是有负数,如果有,初值要置为$-INF$ #include <bits/stdc++.h> using namespace std; ...

  10. hdu 5103 状态压缩dp

    这题说的是给了n(14)个点,每个点都以他 为根的最大可容的孩子个数和最小的可溶孩子个数L[i] ,R[i] 问这n个点形成一棵树有多少种形态 我们让 dp[i][S] 表示 一 i为根节点 的 拥有 ...