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训练 ...
随机推荐
- Windows:子线程中创建窗口
一般来讲,UI的所有操作都必须在主线程,否则会出现未知错误.但有时候我们会需要一个功能比较单一的窗口,同时希望他在一个单独的线程运行.并不影响主线程的效率. 下面说明一下新建子线程创建的新窗口的方法, ...
- python中的下划线(私有变量)
Python用下划线作为变量前缀和后缀指定特殊变量. - "单下划线" 开始的成员变量叫做保护变量,意思是只有类对象和子类对象自己能访问到这些变量:不能用"from xx ...
- SDWebimage清空缓存
清空缓存 - (void)clearTmpPics{ [[SDImageCache sharedImageCache] clearDisk]; [[SDImageCache sharedImageCa ...
- [3D]第一人称相机类Camera
自己根据C++ D3D的源码改写一个相机类(第一人称). using System; using System.Collections.Generic; using System.Linq; usin ...
- POJ1845:Sumdiv(求因子和+逆元+质因子分解)好题
题目链接:http://poj.org/problem?id=1845 定义: 满足a*k≡1 (mod p)的k值就是a关于p的乘法逆元. 为什么要有乘法逆元呢? 当我们要求(a/b) mod p的 ...
- 泰德激光打标软件 包含 #include "Main.h" 时 原本正确的单元却报错
问题:泰德激光打标软件 ,当新增单元需要包含 #include "Main.h" 时, 原本正确的单元却报错. 办法:包含 #include "Main.h" ...
- Java 泛型通配符上限和通配符下限
①为什么要使用泛型通配符 请参考这篇随笔的下半部分 https://www.cnblogs.com/baxianhua/p/9194369.html ②通配符上限和通配符下限的简单解释 <? ...
- An error occurred: No action handlers found - check JMeterHome and libraries
An error occurred: No action handlers found - check JMeterHome and libraries Writing log file to: D: ...
- mongodb-的副本集
复制的重要性不再多说,其主要就是提供数据保护,数据高可用和灾难恢复. 复制是跨多个mongodb服务器分布和维护的方法.mongodb可以把数据从一个节点复制到其他节点并在修改时进行同步. mongo ...
- 使用 log4js UDP 发送数据到 logstash
本文地址 http://www.cnblogs.com/jasonxuli/p/6532723.html 因为 nodejs 一般会部署在多台机器,并且每台机器会起多个进程,因此查看日志时往往要人工区 ...