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

struct RMQSegmentTree(Type = int,string gstr = "a>b"){
	Type[] data;
	size_t height;
	Type initvalue;

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

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

	void SetSize(size_t size){
		size_t s = 1;
		height = 0;
		while(s<size){
			s*=2;
			++height;
		}
		data = new Type[s*2];
		initvalue = Type.max - greatValue(Type.max,Type.min);
		data[] = initvalue;
	}

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

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

	Type GetRMQ(size_t begin,size_t end,size_t depth = -1){
		if(depth == -1)
			depth = height;
		if(begin == end)
			return initvalue;
		size_t blocksize = 1<<depth;
		size_t start = begin - begin%blocksize;
		if(start == begin && start + blocksize == end)
			return data[GetIdx(begin,depth)];
		blocksize /= 2;
		Type 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!long st;
	st.SetSize(n);
	long[] dp = new long[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]);
	}
	long res = 0;
	foreach(i;0..n){
		res += w[i];
	}
	long md = 0;
	foreach(i;0..n){
		md = max(md,dp[i]);
	}
	(res-md).writeln;
}