제출 #1324406

#제출 시각아이디문제언어결과실행 시간메모리
1324406SmuggingSpun전선 연결 (IOI17_wiring)C++20
100 / 100
31 ms7392 KiB
#include "wiring.h"
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>void minimize(T& a, T b){
  if(a > b){
    a = b;
  }
}
const int lim = 1e5 + 5;
const ll INF = 1e18;
int n, m, r[lim], b[lim];
namespace sub1{
  ll solve(){
    vector<ll>dp(m + 1, INF);
    dp[0] = 0;
    for(int i = 1; i <= n; i++){
      vector<ll>ndp(m + 1, INF);
      for(int j = 1; j <= m; j++){
        ndp[j] = dp[j - 1] + abs(r[i] - b[j]);
        for(int k = 1; k <= n; k++){
          minimize(ndp[j], ndp[j - 1] + abs(r[k] - b[j]));
        }  
        for(int k = 1; k <= m; k++){
          minimize(ndp[j], dp[j] + abs(r[i] - b[k]));
        }
      }
      swap(dp, ndp);
    }
    return dp[m];
  }
}
namespace sub2{
  ll solve(){
    ll ans = 0;
    int i = n, j = m;
		while(i > 0 && j > 0){
			ans += b[j--] - r[i--];
		}
		while(i > 0){
			ans += b[1] - r[i--];
		}
		while(j > 0){
			ans += b[j--] - r[n];
		}
    return ans;
  }
}
namespace sub345{
  pair<int, bool>point[lim << 1];
  ll f[lim << 1], dp[lim << 1];
  ll solve(){
    int N = n + m;
    for(int i = 1; i <= n; i++){
      point[i] = make_pair(r[i], false);
    }
    for(int i = 1; i <= m; i++){
      point[n + i] = make_pair(b[i], true);
    }
    sort(point + 1, point + N + 1);
    memset(dp, 0x0f, sizeof(dp));
    f[0] = dp[0] = 0;
    for(int i = 1; i <= N; i++){
      f[i] = f[i - 1] + point[i].first;
    }
    for(int l = 1, r = 1, pre_l = 1; l <= N; pre_l = l, l = r){
      while(r <= N && point[l].second == point[r].second){
        r++;
      }
      if(l > 1){
        ll cost = 0, need = dp[l - 1];
        for(int i = l, j = l; i < r; i++){
          if(j-- > pre_l){
            minimize(need, dp[j - 1] + point[l - 1].first * ll(i - l + 1) - f[l - 1] + f[j - 1]);
          }
          minimize(dp[i], (cost += point[i].first - point[l - 1].first) + need);
        }
      }
      if(r <= N){
        for(int i = l; i < r; i++){
          minimize(dp[i], dp[i - 1] + point[r].first - point[i].first);
        }
      }
    }
    return dp[N];
  }
}
ll min_total_length(vector<int>_r, vector<int>_b){
  for(int i = n = _r.size(); i > 0; i--){
    r[i] = _r[i - 1];
  }
  for(int i = m = _b.size(); i > 0; i--){
    b[i] = _b[i - 1];
  }
  if(max(n, m) <= 200){
    return sub1::solve();
  }
  if(r[n] < b[1]){
    return sub2::solve();
  }
  return sub345::solve();
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...