AOJ 2431 House Moving
問題
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2431
1 から までの整数を並び替えた列 が与えられる。 をコスト で好きな場所に移動できる。昇順にソートするのに必要なコストの最小値を求めよ。
解法
移動させるときはまとめて移動させればいいので、和が最大な増加部分列を求め、それをコストの総和 から引く。
番目まででとれるコストの最大値
とし、普通の最長増加部分列問題のように と更新していった。最大値を探すときに愚直にループを回すと になってしまうのでDP配列を Fenwick 木で持って まで高速化する。
和以外の演算の Fenwick 木を書いたのは初めてだった。
template <typename T> struct fenwick_tree { vector<T> x; fenwick_tree(int n) : x(n, 0) { } T max(int j) { T S = 0; for (; j >= 0; j = (j & (j + 1)) - 1) S = std::max(x[j],S); return S; } void chmax(int k, T a) { for (; k < x.size(); k |= k+1) x[k] = std::max(x[k],a); } }; int main(){ ll n;scanf("%lld",&n); fenwick_tree<ll> dp(n+1); for(int i=0;i<n;i++){ int x;scanf("%d",&x); dp.chmax(x,dp.max(x-1)+x); // for(int i=1;i<=n;i++){ // printf("%lld ",dp.max(i)-dp.max(i-1)); // } // puts(""); } printf("%lld\n",(ll)n*(n+1)/2 - dp.max(n)); }