import std.stdio;
import std.string;
import std.conv;
import std.array;
import std.range;
import std.typecons;
import std.algorithm;

struct RMQSegmentTree(string gstr){
	int[] data;
	int height;
	int initvalue;

	bool greater(int a,int b){
		bool ret;
		mixin("ret = "~gstr~";");
		return ret;
	}

	int greatValue(int a,int b){
		if(greater(a,b))
			return a;
		return b;
	}

	void SetSize(int size){
		int s = 1;
		height = 0;
		while(s<size){
			s*=2;
			++height;
		}
		data = new int[s*2];
		initvalue = 1000000000 - greatValue(1000000000,0);
		data[] = initvalue;
	}

	int GetIdx(int idx,int depth){
		int blocksize = 1<<depth;
		return blocksize-1+(idx/blocksize)*blocksize*2;
	}

	void SetData(int idx,int value,int depth = 0){
		if(depth > height)
			return;
		int gi = GetIdx(idx,depth);
		if(greater(value,data[gi])){
			data[gi] = value;
			SetData(idx,value,depth+1);
		}
	}

	int GetRMQ(int begin,int end,int depth = -1){
		if(depth == -1)
			depth = height;
		if(begin == end)
			return initvalue;
		int blocksize = 1<<depth;
		int start = begin - begin%blocksize;
		if(start == begin && start + blocksize == end)
			return data[GetIdx(begin,depth)];
		blocksize /= 2;
		int ret = initvalue;
		if(begin < start + blocksize)
			ret = greatValue(ret, GetRMQ(begin,min(start + blocksize, end), depth-1));
		if(end > start + blocksize)
			ret = greatValue(ret, GetRMQ(max(begin,start + blocksize), end, depth-1));
		return ret;
	}
}

int[] rdi(){
	return readln.split.map!(to!int).array;
}

void main(){
	int n= rdi[0];
	int[] w;
	w = rdi;
	RMQSegmentTree!"a>b" st;
	st.SetSize(n);
	int[] dp = new int[n];
	dp[] = 0;
	foreach(i;0..n){
		dp[i] = st.GetRMQ(0,w[i]);
		dp[i] += w[i];
		st.SetData(w[i]-1,dp[i]);
	}
	int res = 0;
	foreach(i;0..n){
		res += w[i];
	}
	int md = 0;
	foreach(i;0..n){
		md = max(md,dp[i]);
	}
	(res-md).writeln;
}