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训练 ...
随机推荐
- Romantic---hdu2669(扩展欧几里德模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2669 详解:扩展欧几里德 #include <iostream> #include < ...
- Executor框架与Thread
Executor将线程的创建和线程的执行解耦,比较下面两个例子: 1:TaskExecutionWebServer.java package chapter06; import java.io.IOE ...
- 关于使用ubuntu的那些事儿
最近把笔记本的系统由windows改成了ubuntu的最新版系统了,其实改变系统最主要的目的就是希望自己能够快速的学会使用linux系统. 所以这是一篇记录了关于一个ubuntu小白第一次使用ubun ...
- MySql数据库批量备份命令
rd d:\mysql_data-BAK /s /qmd d:\mysql_data-BAKxcopy d:\mysql_data d:\mysql_data-BAK /e
- 图:无向图(Graph)基本方法及Dijkstra算法的实现 [Python]
一般来讲,实现图的过程中需要有两个自定义的类进行支撑:顶点(Vertex)类,和图(Graph)类.按照这一架构,Vertex类至少需要包含名称(或者某个代号.数据)和邻接顶点两个参数,前者作为顶点的 ...
- 系统管理命令之whoami
whoami命令用于打印当前有效的用户名称,相当于执行id --un命令. 1.显示该命令帮助信息: # whoami --help 2.显示该命令的版本信息: # whoami --version ...
- linux wa%过高,iostat查看io状况
命令总结: 1. top/vmstat 发现 wa%过高,vmstat b >1: 参考文章: 1. 关于Linux系统指令 top 之 %wa 占用高,用`iostat`探个究竟 最近测试一项 ...
- Python笔记 #07# NumPy 文档地址 & Subsetting 2D Arrays
文档地址:np.array() 1.<class 'numpy.ndarray'> ndarray 表示 n 维度(n D)数组 (= n 行数组). 2.打印 array 结构 —— n ...
- pyDay14
内容来自廖雪峰的官方网站. 1.map的优点:省代码 + 提高可读性. 2.map 运用示例: >>> def f(x): ... return x * x ... >> ...
- mongodb的安装和权限管理
mongodb4.0已经发布,但是鉴于线上环境更多的是使用旧版本的mongodb,我们这里使用的mongodb3.4版本. 官网下载地址为:https://fastdl.mongodb.org/lin ...