Submission #834804

#TimeUsernameProblemLanguageResultExecution timeMemory
834804PanosPaskWiring (IOI17_wiring)C++14
100 / 100
38 ms16100 KiB
#include "wiring.h" #include <math.h> #include <iostream> #define pb push_back using namespace std; typedef long long ll; const ll INF = 1e18; struct Group { int cnt; vector<int> positions; int first; int last; // Prefix sums to first, suffix sums to last vector<ll> pref; Group (void) {;} void precalc_group(void) { first = positions.front(); last = positions.back(); cnt = positions.size(); pref.resize(positions.size() + 1); pref[0] = 0; for (int i = 0; i < positions.size(); i++) pref[i + 1] = pref[i] + positions[i]; } ll get_total(int l, int r) { // Returns the sum of positions in the range [l..r) return pref[r] - pref[l]; } int size(void) { return cnt; } }; int N, M; // dp[i][j] : We have paired up everything in groups i - 1 and back, and the first j ones in group i // When processing dp[i][j], we will never touch dp[i - 1] and before again vector<vector<ll>> dp; // Group size for each group vector<Group> groups; long long min_total_length(std::vector<int> r, std::vector<int> b) { N = r.size(); M = b.size(); int cur = -1; int r_p = 0, b_p = 0; while (r_p < r.size() || b_p < b.size()) { int add = 0; if (r_p == r.size()) { add = 1; } else if (b_p == b.size()) { add = 0; } else { if (r[r_p] < b[b_p]) add = 0; else add = 1; } if (cur != add) { // Create new group if (cur != -1) { groups.back().precalc_group(); } groups.pb(Group()); cur = add; } if (add == 0) { groups.back().positions.pb(r[r_p]); r_p++; } else { groups.back().positions.pb(b[b_p]); b_p++; } } groups.back().precalc_group(); dp.resize(groups.size()); dp[0].assign(groups[0].cnt + 1, INF); dp[0][0] = 0; for (int g = 0; g < groups.size() - 1; g++) { dp[g + 1].assign(groups[g + 1].size() + 1, INF); for (int j = 0; j < groups[g].size(); j++) { // The first element to be paired is in position j // Pair it with the leftmost element of the next group dp[g][j + 1] = min(dp[g][j + 1], dp[g][j] + abs(groups[g].positions[j] - groups[g + 1].first)); } for (int j = 0; j <= min(groups[g].size(), groups[g + 1].size()); j++) { // Connect the last j from group g with the first j from group g + 1 // Assume all previous sockets in group g are connected // Number of connected sockets in group g int v = groups[g].size() - j; ll connection_cost = groups[g + 1].get_total(0, j) - groups[g].get_total(groups[g].size() - j, groups[g].size()); dp[g + 1][j] = min(dp[g + 1][j], dp[g][v] + connection_cost); } for (int j = 0; j < groups[g + 1].size(); j++) { // In dp[g + 1][j], the next element to be paired is j // Pair this with the rightmost element of this group dp[g + 1][j + 1] = min(dp[g + 1][j + 1], dp[g + 1][j] + abs(groups[g + 1].positions[j] - groups[g].last)); } } return dp[groups.size() - 1][groups.back().size()]; }

Compilation message (stderr)

wiring.cpp: In member function 'void Group::precalc_group()':
wiring.cpp:33:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   33 |   for (int i = 0; i < positions.size(); i++)
      |                   ~~^~~~~~~~~~~~~~~~~~
wiring.cpp: In function 'long long int min_total_length(std::vector<int>, std::vector<int>)':
wiring.cpp:64:13: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   64 |  while (r_p < r.size() || b_p < b.size()) {
      |         ~~~~^~~~~~~~~~
wiring.cpp:64:31: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   64 |  while (r_p < r.size() || b_p < b.size()) {
      |                           ~~~~^~~~~~~~~~
wiring.cpp:66:11: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   66 |   if (r_p == r.size()) {
      |       ~~~~^~~~~~~~~~~
wiring.cpp:69:16: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   69 |   else if (b_p == b.size()) {
      |            ~~~~^~~~~~~~~~~
wiring.cpp:104:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Group>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  104 |  for (int g = 0; g < groups.size() - 1; g++) {
      |                  ~~^~~~~~~~~~~~~~~~~~~
wiring.cpp:13:8: warning: '<anonymous>.Group::cnt' may be used uninitialized in this function [-Wmaybe-uninitialized]
   13 | struct Group {
      |        ^~~~~
wiring.cpp:13:8: warning: '<anonymous>.Group::first' may be used uninitialized in this function [-Wmaybe-uninitialized]
wiring.cpp:13:8: warning: '<anonymous>.Group::last' may be used uninitialized in this function [-Wmaybe-uninitialized]
#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...