#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
LL a[1000005];
LL mx[1000005];
LL dp[1000005];
int main()
{
int m,n;
while(~scanf("%d%d",&m,&n))
{
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
memset(dp,0,sizeof(dp));
memset(mx,0,sizeof(mx));
LL tmp=-inf;
for(int i=1;i<=m;i++)
{
tmp=-919999999999999999LL;
for(int j=i;j<=n;j++)
{
if(i==j)dp[j]=dp[j-1]+a[j];
else
dp[j]=max(dp[j-1],mx[j-1])+a[j];
mx[j-1]=tmp;
if(dp[j]>tmp)tmp=dp[j];
}
}
cout<<tmp<<endl;
}
}
/*
n个数中取出m段,要求m段的和最大。
每新加入一个数,要么自己独立成一段,要么跟前边那一个数
属于同一段。
所以dp[i][j]表示j个数分i段必须取j的最大值。
对于dp[i][j]=max(dp[i][j-1],max(dp[i-1][k])+a[j]) (k->[1,j-1]);
dp[i][j]的值依赖于dp[i][j-1]和dp[i-1][k];
可以用滚动数组。
其实dp[i-1][k]就是上一行1-(j-1)的最大值,我们可以用一个一维数组记录。
既mx数组。
这样dp数组也可以用一维的了。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
int main()
{
int n;
while(~scanf("%d",&n))
{
int sum=0;
int ans;
for(int i=1;i<=n;i++)
{
int tmp;
sca(tmp);
if(sum==0)
{
ans=tmp;
sum++;
}
else if(tmp==ans)
{
sum++;
}
else sum--;
}
printf("%d\n",ans);
}
}
/*
求出现次数为(n+1)/2次的数,n为奇数
1.排序,中中位数。
2.考虑不同数抵消。最后剩下的是要求的数。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
struct node
{
int x,y,z;
friend bool operator <(node a,node b)
{
if(a.x!=b.x)return a.x<b.x;
else return a.y<b.y;
}
}a[100005];
int dp[10005];
int main()
{
int n;
int cas=1;
while(cin>>n&&n)
{
int cnt=1;
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
a[cnt].x=x,a[cnt].y=y,a[cnt].z=z,cnt++;
a[cnt].x=x,a[cnt].y=z,a[cnt].z=y,cnt++;
a[cnt].x=y,a[cnt].y=x,a[cnt].z=z,cnt++;
a[cnt].x=y,a[cnt].y=z,a[cnt].z=x,cnt++;
a[cnt].x=z,a[cnt].y=x,a[cnt].z=y,cnt++;
a[cnt].x=z,a[cnt].y=y,a[cnt].z=x,cnt++;
}
sort(a+1,a+cnt);
int ans=-199;
for(int i=1;i<cnt;i++)dp[i]=a[i].z;
for(int i=1;i<cnt;i++)
{
for(int j=1;j<i;j++)
{
if(a[j].x<a[i].x&&a[j].y<a[i].y)
{
dp[i]=max(dp[i],dp[j]+a[i].z);
ans=max(ans,dp[i]);
}
}
}
printf("Case %d: maximum height = ",cas++);
cout<<ans<<endl;
}
}
/*
给了一维2微的x和y,一个高度
要求x和y都是严格递减的,求最大高度。其中每种方块都有无限个。
每个方块通过旋转最多产生6种方块。
对一维排序,对另一维求一个最长下降子序列。
如果要求每种块的最大高度就是cdq分治了。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
string str[20];
int dead[20],cost[20];
int dp[1<<16];
int T[1<<16];
int pre[1<<16],name[1<<16];
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
sca(n);
memset(dp,inf,sizeof(dp));
memset(T,0,sizeof(T));
for(int i=0;i<n;i++)
{
cin>>str[i]>>dead[i]>>cost[i];
}
int bit=1<<n;
T[0]=0;
dp[0]=0;
for(int i=1;i<bit;i++)
{
for(int j=n;j>=0;j--)
{
int tmp=1<<j;
if(!(i&tmp))continue;
int tmp1=i^tmp;
int red=max(T[tmp1]+cost[j]-dead[j],0);
int v=dp[tmp1]+red;
//cout<<i<<" "<<j<<" "<<v<<endl;
if(v<dp[i])
{
dp[i]=v;
pre[i]=tmp1;
T[i]=T[tmp1]+cost[j];
name[i]=j;
}
}
}
stack<int>s;
int now=bit-1;
while(now!=0)
{
s.push(name[now]);
now=pre[now];
}
cout<<dp[bit-1]<<endl;
while(!s.empty())
{
cout<<str[s.top()]<<endl;
s.pop();
}
}
}
/*
001 010 011 100 101 110 111
没想到是状态亚索dp
想到了一个比较麻烦的dp
就是依次确定长度为1-n的序列的顺序,然后长度每增加1,我就枚举当前点在
之前序列中的位置。可以确定这样枚举到最后一定能取得最优值。
但是实现起来比较麻烦。因为我们需要不断变换位置,并且统计当前的花费。
仔细想一想,我们其实不用变换位置,因为位置是相对的。
这个状态亚索dp正是利用了这一点吧。
例如n=3 我们有上边8种状态。
当我们枚举i时如果j的位置为1,我们就由之前的状态(j的位置为0)推出当前
i的状态。(这不就相当于把j从原来顺序中拿出来放到最后嘛)。
例如当dp[011]的值确定的时候,我们就相当于确定了当序列的长度为2的时候的
取最优值的一个顺序。
又例如
dp[011] [101] dp[110] 就枚举了长度为2的所有可能的排列。
2 3
3 2
1 3
3 1
1 2
2 1
这就很好解决了上边有思路却无法实现的问题。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
LL a[1005];
LL dp[1005];
int main()
{
int n;
while(cin>>n&&n)
{
for(int i=1;i<=n;i++)scanf("%lld",a+i);
a[0]=-999999999999LL;
a[n+1]=999999999999LL;
memset(dp,0,sizeof(dp));
LL ans=-999999999999;
for(int i=1;i<=n+1;i++)
{
for(int j=0;j<i;j++)
{
if(a[j]<a[i])
{
dp[i]=max(dp[i],dp[j]+a[i]);
ans=max(ans,dp[i]);
}
}
}
cout<<ans-999999999999<<endl;
}
}
/*
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
int dp[100005][12];
int sum[100005][12];
int pos[100005][12];
int M(int x,int y,int z)
{
return max(max(x,y),z);
}
int main()
{
int n;
while(cin>>n&&n)
{
int maxt=0;
memset(dp,0,sizeof(dp));
memset(sum,0,sizeof(sum));
for(int i=1; i<=n; i++)
{
int x,t;
scanf("%d%d",&x,&t);
sum[t][x]++;
maxt=max(maxt,t);
}
int ans=0;
pos[0][5]=1;
for(int i=1; i<=maxt; i++)
{
for(int j=0;j<=10;j++)
{
if(pos[i-1][j]==1)pos[i][j]=pos[i][j-1]=pos[i][j+1]=1;
}
for(int k=0; k<=10; k++)
{
if(pos[i][k]==0)continue;
if(k==0)dp[i][k]=max(dp[i-1][k],dp[i-1][k+1])+sum[i][k];
else if(k==10)dp[i][k]=max(dp[i-1][k],dp[i-1][k-1])+sum[i][k];
else dp[i][k]=M(dp[i-1][k-1],dp[i-1][k],dp[i-1][k+1])+sum[i][k];
ans=max(ans,dp[i][k]);
}
}
cout<<ans<<endl;
}
}
/*
对于每一个时刻,处理处下一时刻能到达的位置。
然后对能到达的位置进行状态转移。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
struct node
{
int p,w;
}a[505];
int dp[3][10005];
int main()
{
int t;
sca(t);
while(t--)
{
int e,f;
scanf("%d%d",&e,&f);
int n;
sca(n);
for(int i=1;i<=n;i++)
{
sca(a[i].p),sca(a[i].w);
}
memset(dp,inf,sizeof(dp));
int W=f-e;
dp[0][0]=0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=W;j++)
{
if(j<a[i].w)dp[(i)%2][j]=dp[(i-1)%2][j];
else dp[i%2][j]=min(dp[(i-1)%2][j],dp[i%2][j-a[i].w]+a[i].p);
//cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;
}
}
if(dp[n%2][W]==inf)puts("This is impossible.");
else printf("The minimum amount of money in the piggy-bank is %d.\n",dp[n%2][W]);
}
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
int dp[100005][12];
int sum[100005][12];
int pos[100005][12];
int M(int x,int y,int z)
{
return max(max(x,y),z);
}
int main()
{
int n;
while(cin>>n&&n)
{
int maxt=0;
memset(dp,0,sizeof(dp));
memset(sum,0,sizeof(sum));
for(int i=1; i<=n; i++)
{
int x,t;
scanf("%d%d",&x,&t);
sum[t][x]++;
maxt=max(maxt,t);
}
int ans=0;
pos[0][5]=1;
for(int i=1; i<=maxt; i++)
{
for(int j=0;j<=10;j++)
{
if(pos[i-1][j]==1)pos[i][j]=pos[i][j-1]=pos[i][j+1]=1;
}
for(int k=0; k<=10; k++)
{
if(pos[i][k]==0)continue;
if(k==0)dp[i][k]=max(dp[i-1][k],dp[i-1][k+1])+sum[i][k];
else if(k==10)dp[i][k]=max(dp[i-1][k],dp[i-1][k-1])+sum[i][k];
else dp[i][k]=M(dp[i-1][k-1],dp[i-1][k],dp[i-1][k+1])+sum[i][k];
ans=max(ans,dp[i][k]);
}
}
cout<<ans<<endl;
}
}
/*
对于每一个时刻,处理处下一时刻能到达的位置。
然后对能到达的位置进行状态转移。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
int a[2005];
int b[2005];
int dp[2005][2];
int main()
{
int t;
sca(t);
while(t--)
{
int n;
sca(n);
for(int i=1;i<=n;i++)sca(a[i]);
for(int i=1;i<n;i++)sca(b[i]);
memset(dp,inf,sizeof(dp));
dp[1][0]=dp[1][1]=a[1];
dp[2][1]=a[1]+a[2];
dp[2][0]=b[1];
for(int i=3;i<=n;i++)
{
dp[i][0]=min(dp[i-1][1],min(dp[i-2][0],dp[i-2][1]))+b[i-1];
dp[i][1]=min(dp[i-1][1],dp[i-1][0])+a[i];
}
int en=min(dp[n][0],dp[n][1]);
int h=(8+en/3600)%24;
en%=3600;
int f=en/60;
en%=60;
int flag=0,tmp=0;
if(h>=12)
{
flag=1;
}
printf("%02d:%02d:%02d ",h,f,en);
if(flag)puts("pm");
else puts("am");
}
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
int a[10005],b[10005];
int cnt;
int erfen(int val)
{
int l=1,r=cnt;
while(l<=r)
{
int m=(l+r)>>1;
if(val<=b[m])r=m-1;
else l=m+1;
}
//cout<<l<<" "<<r<<endl;
return r+1;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)sca(a[i]);
b[1]=a[1];
cnt=1;
for(int i=2;i<=n;i++)
{
int pos=erfen(a[i]);
b[pos]=a[i];
//cout<<pos<<endl;
if(pos>cnt)cnt++;
}
cout<<cnt<<endl;
}
}
/*
1 4 2
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
struct node
{
int a,b,id;
friend bool operator <(node x,node y)
{
return x.a<y.a;
}
}c[1005],d[1005];
int dp[1005];
int path[1005];
void Pri(int p)
{
if(p==0)return ;
Pri(path[p]);
cout<<d[p].id<<endl;
}
int main()
{
int cnt=1;
while(cin>>c[cnt].a>>c[cnt].b)
{
c[cnt].id=cnt;
cnt++;
}
sort(c+1,c+cnt);
int now=1;
for(int i=1;i+1<=cnt;i++)
{
d[now]=c[i];
//cout<<c[i].a<<" "<<c[i].b<<endl;
if(c[i].a==c[i+1].a&&c[i].b==c[i+1].b)continue;
now++;
}
int ans=0;
for(int i=1;i<now;i++)
{
for(int j=1;j<i;j++)
{
if(d[i].b<d[j].b&&d[i].a!=d[j].a)
{
if(dp[i]<dp[j]+1)
{
dp[i]=dp[j]+1;
path[i]=j;
ans=max(ans,dp[i]);
}
}
}
}
int pos;
for(int i=now-1;i>=0;i--)
{
if(dp[i]==ans)
{
pos=i;
break;
}
}
cout<<ans+1<<endl;
Pri(pos);
}
这个应该是最难得一个了,转化为背包问题求解,n代表物品,m代表背包容量。
枚举绝差值,进行状态转移。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<vector>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
#define N 205
int dp[2][22][805];
int c[N],d[N];
int a[N],b[N];
vector<int>path[2][22][805];
void init()
{
for(int i=0;i<2;i++)
{
for(int j=0;j<22;j++)
{
for(int k=0;k<804;k++)path[i][j][k].clear();
}
}
}
int main()
{
int n,m;
int cas=1;
while(cin>>n>>m&&(n+m))
{
init();
for(int i=1;i<=n;i++)
{
sca(a[i]),sca(b[i]);
c[i]=a[i]+b[i];
d[i]=a[i]-b[i];
}
memset(dp,-1,sizeof(dp));
int fix=20*m;
dp[0][0][fix]=0;
for(int i=1;i<=n;i++)
{
dp[i%2][0][fix]=0;
for(int j=1;j<=m;j++)
{
for(int k=d[i];k<=20*m+fix;k++)
{
if(dp[(i-1)%2][j][k]!=-1)dp[i%2][j][k]=dp[(i-1)%2][j][k],path[i%2][j][k]=path[(i-1)%2][j][k];
if(dp[(i-1)%2][j-1][k-d[i]]==-1)continue;
if(k<0||k-d[i]>20*m+fix)continue;
if(dp[(i-1)%2][j-1][k-d[i]]+c[i]>dp[i%2][j][k])
{
dp[i%2][j][k]=dp[(i-1)%2][j-1][k-d[i]]+c[i];
path[i%2][j][k]=path[(i-1)%2][j-1][k-d[i]];
path[i%2][j][k].pb(i);
//cout<<i<<" "<<j<<" "<<k<<" = "<<dp[i][j][k]<<endl;
}
//else dp[i][j][now]=dp[i-1][j-1][now];
}
}
}
int state=0;
while(dp[n%2][m][fix-state]==-1&&dp[n%2][m][fix+state]==-1)state++;
state=dp[n%2][m][fix-state]>dp[n%2][m][fix+state]?(fix-state):(fix+state);
//cout<<path[n%2][m][state].size()<<endl;
int ans1=0,ans2=0;
for(int i=0;i<path[n%2][m][state].size();i++)ans1+=a[path[n%2][m][state][i]],ans2+=b[path[n%2][m][state][i]];
printf("Jury #%d\n",cas++);
printf("Best jury has value %d for prosecution and value %d for defence:\n",ans1,ans2);
for(int i=0;i<path[n%2][m][state].size();i++)
{
printf("%d",path[n%2][m][state][i]);
if(i==path[n%2][m][state].size()-1)printf("\n");
else printf(" ");
}
printf("\n");
}
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
char s1[1005],s2[1005];
int dp[1005][1005];
int main()
{
while(~scanf("%s%s",s1+1,s2+1))
{
int len1=strlen(s1+1);
int len2=strlen(s2+1);
memset(dp,0,sizeof(dp));
for(int i=1;i<=len1;i++)
{
for(int j=1;j<=len2;j++)
{
if(s1[i]==s2[j])
{
dp[i][j]=dp[i-1][j-1]+1;
}
else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
cout<<dp[len1][len2]<<endl;
}
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
int a[10005],b[10005];
int cnt;
int erfen(int val)
{
int l=1,r=cnt;
while(l<=r)
{
int m=(l+r)>>1;
if(val<=b[m])r=m-1;
else l=m+1;
}
//cout<<l<<" "<<r<<endl;
return l;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)sca(a[i]);
b[1]=a[1];
cnt=1;
for(int i=2;i<=n;i++)
{
int pos=erfen(a[i]);
b[pos]=a[i];
//cout<<pos<<endl;
if(pos>cnt)cnt++;
}
cout<<cnt<<endl;
}
}
/*
1 4 2
*/
区间dp
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
int dp[2005][2005];
int sum[2005];
int a[2005];
int S(int l,int r)
{
if(l>r)return 0;
return sum[r]-sum[l-1];
}
int DP(int l,int r)
{
if(l>r)return 0;
if(l==r)return a[l];
if(dp[l][r]!=0)return dp[l][r];
else dp[l][r]=max(a[l]+DP(l+1,r)+S(l+1,r),a[r]+DP(l,r-1)+S(l,r-1));
return dp[l][r];
}
int main()
{
int n;
sca(n);
for(int i=1;i<=n;i++)sca(a[i]);
for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
cout<<DP(1,n)<<endl;
}
/*
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
int n,k;
int a[105][105];
int dp[105][105];
bool judge(int x,int y,int x1,int y1)
{
if(x1<1||x1>n||y1<1||y1>n)return false;
if(a[x1][y1]<=a[x][y])return false;
return true;
}
int DP(int x,int y)
{
if(dp[x][y])return dp[x][y];
int flag=0;
for(int i=1;i<=2;i++)
{
for(int j=-k;j<=k;j++)
{
int x1,y1;
if(i==1)x1=x,y1=y+j;
if(i==2)y1=y,x1=x+j;
if(judge(x,y,x1,y1))
{
flag=1;
dp[x][y]=max(dp[x][y],DP(x1,y1));
}
}
}
if(!flag)dp[x][y]=a[x][y];
else dp[x][y]+=a[x][y];
return dp[x][y];
}
int main()
{
while(cin>>n>>k)
{
if(n==-1&&k==-1)break;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)sca(a[i][j]);
}
memset(dp,0,sizeof(dp));
cout<<DP(1,1)<<endl;
}
}
/*
*/
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define mp(x,y) make_pair(x,y)
#define N 1000005
#define O2 __attribute__((optimize("O2")))
char s[1005][1005];
int dp[1005][1005];
O2 int main()
{
int n;
while(cin>>n&&n)
{
for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
memset(dp,0,sizeof(dp));
int x=1,y=n;
int ans=0;
for(int i=1;i<=n;i++)
{
for(int j=n;j>=1;j--)
{
int x=i,y=j;
int cnt=0;
while(x>=1&&x<=n&&y>=1&&y<=n&&s[x][j]==s[i][y])cnt++,x--,y++;
if(cnt>dp[i-1][j+1])ans=max(ans,dp[i-1][j+1]+1),dp[i][j]=dp[i-1][j+1]+1;
else ans=max(ans,dp[i][j]),dp[i][j]=cnt;
//cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;
}
}
cout<<ans<<endl;
}
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
struct node
{
int x,y;
LL w;
friend bool operator <(node a,node b)
{
return a.x==b.x?a.y<b.y:a.x<b.x;
}
}a[10005];
LL dp[10005];
bool judge(int i,int j)
{
return a[j].x>=a[i].y;
}
int main()
{
int n,m,r;
cin>>n>>m>>r;
for(int i=1;i<=m;i++)
{
sca(a[i].x),sca(a[i].y);
scanf("%lld",&a[i].w);
a[i].y+=r;
}
sort(a+1,a+1+m);
LL ans=0;
for(int i=1;i<=m;i++)dp[i]=a[i].w;
for(int i=1;i<=m;i++)
{
for(int j=i+1;j<=m;j++)
{
if(judge(i,j))
{
dp[j]=max(dp[j],dp[i]+a[j].w);
ans=max(ans,dp[j]);
}
//cout<<j<<" "<<i<<" "<<dp[i]<<endl;
}
}
cout<<ans<<endl;
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<cmath>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
#define N 2005
#pragma G++ optimize(2)
int a[N],b[N];
LL dp[N][N];
void solve(int n,int m)
{
for(int i=1;i<=n;i++)
{
LL tmp=1LL<<60;
for(int j=1;j<=m;j++)
{
tmp=min(tmp,dp[i-1][j]);
dp[i][j]+=tmp;
dp[i][j]+=abs(b[j]-a[i]);
//cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;
}
}
LL ans=1LL<<60;
for(int i=1;i<=m;i++)ans=min(ans,dp[n][i]);
cout<<ans<<endl;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)sca(a[i]),b[i]=a[i];
int cnt=0;
sort(b+1,b+1+n);
for(int i=1;i<=n;i++)if(i==1||b[i]!=b[i-1])b[++cnt]=b[i];
solve(n,cnt);
}