【BZOJ】【1049】【HAOI2006】数字序列

DP


  第一问比较水……a[i]-=i 以后就变成最长不下降子序列问题了,第二问这个结论好神奇,考试的时候怎么破?大胆猜想,不用证明?TAT

  题解:http://pan.baidu.com/share/link?uk=2651016602&shareid=1490516411

没有将a[0]置为-INF在BZOJ上WA了……so sad……

 /**************************************************************
Problem: 1049
User: Tunix
Language: C++
Result: Accepted
Time:260 ms
Memory:2912 kb
****************************************************************/ //BZOJ 1049
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
inline int getint(){
int v=,sign=; char ch=getchar();
while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
return v*sign;
}
const int N=,INF=~0u>>;
typedef long long LL;
/******************tamplate*********************/
int head[N],to[N],next[N],cnt;
void ins(int x,int y){
to[++cnt]=y; next[cnt]=head[x]; head[x]=cnt;
}
int n,a[N],b[N],f[N],len;
int Find(int x){
int l=,r=len,mid,ans=;
while(l<=r){
mid=l+r>>;
if (b[mid]<=x) ans=mid,l=mid+;
else r=mid-;
}
return ans+;
}
LL g[N],sum1[N],sum2[N];
void solve2(){
D(i,n,){
ins(f[i],i);
g[i]=1LL<<;
}
g[]=;
a[]=-<<;//这句必须有,不然在BZOJ上会WA……
F(x,,n)
for(int i=head[f[x]-];i;i=next[i]){//枚举从哪个地方转移过来
if (to[i]>x) break;
if (a[to[i]]>a[x]) continue;
for(int k=to[i];k<=x;k++)
sum1[k]=abs(a[k]-a[to[i]]),sum2[k]=abs(a[x]-a[k]);
for(int k=to[i]+;k<=x;k++)
sum1[k]+=sum1[k-],sum2[k]+=sum2[k-];
for(int k=to[i];k<x;k++)
g[x]=min(g[x],g[to[i]]+sum1[k]-sum1[to[i]]+sum2[x]-sum2[k]);
}
cout <<g[n]<<endl;
}
int main(){
n=getint();
F(i,,n) a[i]=getint()-i;
a[++n]=<<;
F(i,,n){
int x=Find(a[i]);
f[i]=x; b[x]=a[i];
if (x>len) len=x;
}
// F(i,1,n) printf("%d ",f[i]);puts("");
printf("%d\n",n-f[n]);//task 1 end
solve2();
return ;
}

1049: [HAOI2006]数字序列

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1022  Solved: 410
[Submit][Status][Discuss]

Description

现在我们有一个长度为n的整数序列A。但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列。但是不希望改变过多的数,也不希望改变的幅度太大。

Input

第一行包含一个数n,接下来n个整数按顺序描述每一项的键值。

Output

第一行一个整数表示最少需要改变多少个数。 第二行一个整数,表示在改变的数最少的情况下,每个数改变的绝对值之和的最小值。

Sample Input

4
5 2 3 5

Sample Output

1
4

HINT

【数据范围】

90%的数据n<=6000。

100%的数据n<=35000。

保证所有数列是随机的。

Source

[Submit][Status][Discuss]

上一篇:maven搭建多模块企业级项目


下一篇:ubuntu编译运行xv6