zoukankan      html  css  js  c++  java
  • Leetcode 1021. Best Sightseeing Pair

    題意

    給定一個數組,求 Aj + Ai - (j - i) 的最大值,其中 j > i,數組長度範圍是 50000。

    題解

    Aj + Ai - (j - i) = (Aj - j) + (Ai + i)

    所以我們可以把原來的數組 a 轉化成兩個數組 aj, ai,其中 ajj = Aj - j, aii = Ai + i,那麼 max{aii + ajj} (i<j) 即爲所求。

    假設 ajj 固定,如果能夠知道 max{aii} (i<j) 的話,那麼對於前 j 個數字,最大值就得到了。於是我們可以提前求出前 i 個數字的 max{ai},記爲數組 pai,複雜度是 O(n)。然後循環 aj 數組,得到 ajj + paij-1 的最大值即爲題目所求,這一步複雜度還是 O(n)。整個複雜度是 O(n)。

     1 class Solution {
     2 public:
     3     int maxScoreSightseeingPair(vector<int>& A) {
     4       VI ai(A.size()), aj(A.size()), pai(A.size());
     5       int res=-1;
     6       REP(i, A.size()) {
     7         ai[i]=A[i]+i;
     8         aj[i]=A[i]-i;
     9         if(i==0) {
    10           pai[i]=ai[i];
    11         } else {
    12           pai[i]=max_(pai[i-1],ai[i]);
    13           res=max_(res,pai[i-1]+aj[i]);
    14         }
    15       }
    16       return res;
    17     }
    18 };
    ︿<(= ̄︶ ̄=)>︿

    在這個基礎上優化代碼:

     1 class Solution {
     2 public:
     3     int maxScoreSightseeingPair(vector<int>& A) {
     4       // A.size() >= 2
     5       VI  pai(A.size());
     6       int res=A[1]+A[0]-1;
     7       pai[0]=A[0];
     8       REP_1(i, A.size()-1) {
     9         pai[i]=max_(pai[i-1],A[i]+i);
    10         res=max_(res,pai[i-1]+A[i]-i);
    11       }
    12       return res;
    13     }
    14 };
    ~o=(`▽`o=)>~=3=3=3

    觀察數組的使用方式,發現後一個元素只依賴於前一個元素,所以還可以再優化:

     1 class Solution {
     2 public:
     3     int maxScoreSightseeingPair(vector<int>& A) {
     4       // A.size() >= 2
     5       int res=A[1]+A[0]-1, tmp=A[0];
     6       REP_1(i, A.size()-1) {
     7         res=max_(res,tmp+A[i]-i);
     8         tmp=max_(tmp,A[i]+i);
     9       }
    10       return res;
    11     }
    12 };
    <(= ̄3 ̄)╭❤

    這樣可讀性其實變差了,但是節省了空間。

    最後貼上完整的代碼:

      1 // ==================================================
      2 
      3 // C library
      4 #include <cassert>
      5 #include <cmath>
      6 #include <climits>
      7 #include <cstdio>
      8 #include <cstdlib>
      9 #include <cstring>
     10 #include <cctype>
     11 #include <ctime>
     12 
     13 // Containers
     14 #include <vector>
     15 #include <list>
     16 #include <stack>
     17 #include <queue>
     18 #include <deque>
     19 #include <set>
     20 #include <map>
     21 #include <unordered_set>
     22 #include <unordered_map>
     23 
     24 // Input/Output
     25 #include <iostream>
     26 #include <istream>
     27 #include <ostream>
     28 #include <sstream>
     29 #include <fstream>
     30 #include <ios>
     31 #include <iomanip>
     32 
     33 // Other
     34 #include <tuple>
     35 #include <string>
     36 #include <tuple>
     37 #include <bitset>
     38 #include <algorithm>
     39 #include <utility>
     40 #include <type_traits>
     41 #include <iterator>
     42 #include <limits>
     43 #include <stdexcept>
     44 #include <random>
     45 #include <chrono>
     46 
     47 // ==================================================
     48 
     49 using namespace std;
     50 
     51 // constants
     52 const double EPS = 1e-9;
     53 
     54 // type alias
     55 using PII = pair<int, int>;
     56 using LL = long long int;
     57 using VI = vector<int>;
     58 using VC = vector<char>;
     59 using VS = vector<string>;
     60 using VVI = vector<VI>;
     61 using MII = map<int, int>;
     62 using MCI = map<char, int>;
     63 using SI = set<int>;
     64 
     65 // ==================================================
     66 
     67 // fast IO
     68 static auto __2333__ = []() {
     69                          ios::sync_with_stdio(false); cin.tie(nullptr); return 0; }();
     70 
     71 // ==================================================
     72 
     73 // some macro for less typing
     74 #define max_(x, y) ((x) > (y) ? (x) : (y))
     75 #define min_(x, y) ((x) > (y) ? (y) : (x))
     76 
     77 #define REP(i, n) for (int i = 0; i < int(n); ++i) // [0, n)
     78 #define REPV(i, n) for (int i = int(n - 1); i >= 0; --i)   // reverse [0, n)
     79 #define FOR(i, a, b) for (int i = int(a); i < int(b); ++i) // [a, b)
     80 #define DWN(i, b, a) for (int i = int(b - 1); i >= int(a); --i) // reverse [a, b)
     81 
     82 #define REP_1(i, n) for (int i = 1; i <= int(n); ++i)           // [1, n]
     83 #define REPV_1(i, n) for (int i = int(n); i >= 1; --i)          // reverse [1, n]
     84 #define FOR_1(i, a, b) for (int i = int(a); i <= int(b); ++i)   // [a, b]
     85 #define DWN_1(i, b, a) for (int i = int(b); i >= a; --i)        // reverse [a, b]
     86 
     87 // DEBUG PRINT macro
     88 #define PR(x) cout << #x " = " << (x) << "	"
     89 #define NL cout << "
    "
     90 
     91 #define PR1(x) PR(x), NL
     92 #define PR2(x1, x2) PR(x1), PR1(x2)
     93 #define PR3(x1, x2, x3) PR(x1), PR2(x2, x3)
     94 #define PR4(x1, x2, x3, x4) PR(x1), PR3(x2, x3, x4)
     95 
     96 int direction[8][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1},
     97                                                     {-1, -1}, {-1, 1}, {1, -1}, {1, 1} };
     98 
     99 // ==================================================
    100 
    101 // simplest print
    102 template<typename T>
    103 void PRC(const T& a) { cout << a << " "; }
    104 
    105 // print container
    106 template<typename T>
    107 void PRCO(const T& c) { for (auto x : c) PRC(x); NL; }
    108 
    109 // print vector
    110 template<typename T>
    111 void PRV(const vector<T>& c) { PRCO<vector<T>>(c); }
    112 
    113 // print C-style array
    114 template<typename T, size_t N>
    115 void PRA(const T (&ar)[N]) {
    116   for (auto x : ar) PRC(x); NL;
    117 }
    118 
    119 // print pair
    120 template<typename T1, typename T2>
    121 void PRP(const pair<T1, T2>& p) { PRC(p.first); PRLN(p.second); }
    122 
    123 // print a value and a new line
    124 template<typename T>
    125 void PRLN(const T& a) { cout << a << "
    "; }
    126 
    127 // ==================================================
    128 // math
    129 bool is_prime(LL x)
    130 {
    131   if (x == 1) return false;
    132   assert(x > 1);
    133   LL m = ceil(sqrt(x));
    134   FOR_1(i, 2, m) { if (!(x % i)) return false; }
    135   return true;
    136 }
    137 
    138 // prime table
    139 const int PRIME_MAX = 10;
    140 VI prime_table;
    141 vector<bool> prime_table_bool(PRIME_MAX, true);
    142 
    143 void get_prime() {
    144   FOR_1(i, 2, PRIME_MAX) {
    145     if (prime_table_bool[i]) {
    146       prime_table.push_back(i);
    147       for (int j = i << 1; j <= PRIME_MAX; j += i) prime_table_bool[j] = false;
    148     }
    149   }
    150 }
    151 
    152 // double equals
    153 bool eq(double a, double b) { return fabs(a - b) < EPS; }
    154 
    155 double random_() {
    156   // generate random number in [0, 1]
    157   return double(rand()) / RAND_MAX;
    158 }
    159 
    160 int random_(int m) {
    161   // generate random int between [0, m - 1]
    162   return int(random_() * (m - 1) + 0.5);
    163 }
    164 
    165 // high precision integer
    166 
    167 class BNI {
    168   friend ostream &operator<<(ostream &, const BNI &);
    169   friend istream &operator>>(istream &, BNI &);
    170 public:
    171   BNI() = default;
    172   BNI(const string &s) { *this = s; }
    173   BNI(const char s[]) :BNI(string(s)) {}
    174   BNI(const BNI &rhs) = default;
    175   BNI(const LL n) { *this = n; };
    176   BNI(istream &in) { string s; in >> s; *this = s; }
    177 
    178   BNI &operator=(const BNI &rhs) = default;
    179   BNI &operator=(const string &s) {
    180     string s_ = clean_zero_str(s);
    181     num.resize(s_.size());
    182     int i = 0;
    183     for (auto it = s_.crbegin(); it != s_.crend(); ++it)
    184       num[i++] = *it - '0';
    185     return *this;
    186   }
    187   BNI &operator=(const char s[]) {
    188     operator=(string(s));
    189     return *this;
    190   }
    191   BNI &operator=(LL n) {
    192     stringstream ss; ss << n;
    193     string s; ss >> s;
    194     *this = s;
    195     return *this;
    196   }
    197   BNI operator+(const BNI &rhs) const {
    198     BNI res;
    199     size_t max_len = max_(num.size(), rhs.num.size());
    200     int x;
    201     for (int i = 0, rem = 0; rem || i < max_len; ++i) {
    202       x = rem;
    203       if (i < num.size()) x += num[i];
    204       if (i < rhs.num.size()) x += rhs.num[i];
    205       res.num.push_back(x % 10);
    206       rem = x / 10;
    207     }
    208     res.clean_zero();
    209     return res;
    210   }
    211   BNI& operator+=(const BNI &rhs) {
    212     *this = *this + rhs;
    213     return *this;
    214   }
    215   BNI operator*(const BNI &rhs) const {
    216     BNI res;
    217     size_t sum_len = num.size() + rhs.num.size();
    218     res.num.resize(sum_len);
    219     for (size_t i = 0; i < num.size(); ++i) {
    220       for (size_t j = 0; j < rhs.num.size(); ++j) {
    221         res.num[i + j] += num[i] * rhs.num[j];
    222       }
    223     }
    224     for (size_t i = 0; i < res.num.size() - 1; ++i) {
    225       res.num[i + 1] += res.num[i] / 10;
    226       res.num[i] %= 10;
    227     }
    228     res.clean_zero();
    229     return res;
    230   }
    231   BNI& operator*=(const BNI &rhs) {
    232     *this = *this * rhs;
    233     return *this;
    234   }
    235   /*
    236    * assume *this >= rhs
    237    */
    238   BNI operator-(const BNI &rhs) const {
    239     assert(*this >= rhs);
    240     if (rhs == 0LL) return *this;
    241     BNI res;
    242     int x;
    243     for (int i = 0, rem = 0; i < num.size(); ++i) {
    244       x = num[i] - rem;
    245       if (i < rhs.num.size()) x -= rhs.num[i];
    246       if (x >= 0) rem = 0;
    247       else { rem = 1; x += 10; }
    248       res.num.push_back(x);
    249     }
    250     res.clean_zero();
    251     return res;
    252   }
    253   BNI& operator-=(const BNI &rhs) {
    254     *this = *this - rhs;
    255     return *this;
    256   }
    257   /*
    258    * assume rhs is not zero
    259    */
    260   pair<BNI, BNI> operator/(const BNI &rhs) const {
    261     assert(BNI(0LL) != rhs);
    262     if (*this < rhs) return make_pair(0LL, *this);
    263 
    264     BNI quotient, rem;
    265     string nume = c_str();
    266     string numerator = nume.substr(0, rhs.num.size());
    267     size_t pos = rhs.num.size();
    268     vector<BNI> times(10);
    269     for (int i = 0; i < 10; ++i) times[i] = rhs * i;
    270     string quot;
    271 
    272     while (pos <= nume.size()) {
    273       BNI nume_b = numerator;
    274       int cnt = 0;
    275 
    276       while (cnt < 10 && times[cnt] <= nume_b) ++cnt;
    277       --cnt;
    278 
    279       quot += char(cnt + '0');
    280       rem = nume_b - times[cnt];
    281 
    282       if (pos < nume.size())
    283         numerator = rem.c_str() + nume[pos];
    284 
    285       ++pos;
    286     }
    287 
    288     quotient = quot;
    289 
    290     return make_pair(quotient, rem);
    291   }
    292   bool operator<(const BNI &rhs) const {
    293     if (num.size() == 0) return !(rhs.num.size() == 0);
    294     if (num.size() != rhs.num.size()) {
    295       return num.size() < rhs.num.size();
    296     }
    297     for (int i = num.size() - 1; i >= 0; --i) {
    298       if (num[i] != rhs.num[i]) return num[i] < rhs.num[i];
    299     }
    300     return false;
    301   }
    302   bool operator>(const BNI &rhs) const { return rhs < *this; }
    303   bool operator<=(const BNI &rhs) const { return !(*this > rhs); }
    304   bool operator>=(const BNI &rhs) const { return !(*this < rhs); }
    305   bool operator!=(const BNI &rhs) const { return (*this < rhs) || (*this > rhs); }
    306   bool operator==(const BNI &rhs) const { return !(*this != rhs); }
    307   size_t size() const { return num.size(); }
    308   string c_str() const {
    309     string s;
    310     for (auto x : num) s = char(x + '0') + s;
    311     return s.empty() ? "0" : s;
    312   }
    313   void left_shift() {
    314     if (!num.empty()) num.pop_back();
    315   }
    316 protected:
    317   vector<int> num;
    318   string clean_zero_str(const string &s) {
    319     if (s.empty() || s[0] != '0') return s;
    320     size_t i = 0;
    321     while (i < s.size() && '0' == s[i]) ++i;
    322     return s.substr(i);
    323   }
    324   void clean_zero() {
    325     for (auto it = num.rbegin(); it != num.rend() && *it == 0;) {
    326       ++it;
    327       num.pop_back();
    328     }
    329   }
    330 };
    331 
    332 ostream &operator<<(ostream &out, const BNI &x) {
    333   out << x.c_str();
    334   return out;
    335 }
    336 
    337 istream &operator>>(istream &in, BNI &x) {
    338   x = BNI(in);
    339   return in;
    340 }
    341 
    342 // high precision float
    343 class BNF : protected BNI {
    344   friend ostream &operator<<(ostream &out, const BNF &x);
    345   friend istream &operator>>(istream &in, BNF &x);
    346 public:
    347   BNF() = default;
    348   BNF(const string &s) { *this = s; }
    349   BNF(const char s[]): BNF(string(s)) {}
    350   BNF(const BNF &rhs) = default;
    351   BNF(const LL n) { *this = n; }
    352   BNF(istream &in) { string s; in >> s; *this = s; }
    353 
    354   BNF &operator=(const string &s) {
    355     string s_ = clean_zero_str(s);
    356     num.resize(s_.size());
    357     int i = 0;
    358     for (auto it = s_.crbegin(); it != s_.crend(); ++it)
    359       num[i++] = *it - '0';
    360     return *this;
    361   }
    362   BNF &operator=(const char s[]) {
    363     operator=(string(s)); return *this;
    364   }
    365   BNF &operator=(LL n) {
    366     stringstream ss; ss << n;
    367     string s; ss >> s;
    368     *this = s;
    369     return *this;
    370   }
    371   BNF operator+(const BNF &rhs) const {
    372     pair<string, string> in_fr1 = split(), in_fr2 = rhs.split();
    373     string inte1 = in_fr1.first, frac1 = in_fr1.second,
    374       inte2 = in_fr2.first, frac2 = in_fr2.second;
    375     LL inc = 0LL;
    376     BNI frac_sum;
    377     inc += sum_has_carry(frac1, frac2, frac_sum);
    378     BNI inte_sum = BNI(inte1) + inte2 + inc;
    379 
    380     return join_inte_frac(inte_sum, frac_sum);
    381   }
    382   BNF& operator+=(const BNF &rhs) {
    383     *this = *this + rhs;
    384     return *this;
    385   }
    386   /*
    387    * assume *this >= rhs
    388    */
    389   BNF operator-(const BNF &rhs) const {
    390     assert(*this >= rhs);
    391     pair<string, string> in_fr1 = split(), in_fr2 = rhs.split();
    392     string inte1 = in_fr1.first, frac1 = in_fr1.second,
    393       inte2 = in_fr2.first, frac2 = in_fr2.second;
    394     LL dec = 0LL;
    395     if (BNI(frac1) < frac2) {
    396       frac1 = '1' + frac1; ++dec;
    397     }
    398     while (frac1.size() < frac2.size()) frac1 += '0';
    399     while (frac2.size() < frac1.size()) frac2 += '0';
    400     BNI frac = BNI(frac1) - frac2;
    401     BNI inte = BNI(inte1) - dec - inte2;
    402     return join_inte_frac(inte, frac);
    403   }
    404   BNF& operator-=(const BNF &rhs) {
    405     return *this = *this - rhs;
    406   }
    407   BNF operator*(const BNF &rhs) const {
    408     pair<string, string> in_fr1 = split(), in_fr2 = rhs.split();
    409     string inte1 = in_fr1.first, frac1 = in_fr1.second,
    410       inte2 = in_fr2.first, frac2 = in_fr2.second;
    411     BNI res = BNI(inte1 + frac1) * (inte2 + frac2);
    412     int deci = decimals + rhs.decimals;
    413     string res_s = res.c_str();
    414     while (res_s.size() < deci) res_s = '0' + res_s;
    415     return BNF(res_s.substr(0, res_s.size() - deci) + '.'
    416                + res_s.substr(res_s.size() - deci));
    417   }
    418   BNF& operator*=(const BNF &rhs) {
    419     return *this = *this * rhs;
    420   }
    421   bool operator<(const BNF &rhs) const {
    422     pair<string, string> in_fr1 = split(), in_fr2 = rhs.split();
    423     string inte1 = in_fr1.first, frac1 = in_fr1.second,
    424       inte2 = in_fr2.first, frac2 = in_fr2.second;
    425     if (inte1 < inte2) return true;
    426     else if (inte1 == inte2) return frac1 < frac2;
    427     else return false;
    428   }
    429   bool operator>(const BNF &rhs) const { return rhs < *this; }
    430   bool operator<=(const BNF &rhs) const { return !(*this > rhs); }
    431   bool operator>=(const BNF &rhs) const { return !(*this < rhs); }
    432   bool operator!=(const BNF &rhs) const { return (*this < rhs) || (*this > rhs); }
    433   bool operator==(const BNF &rhs) const { return !(*this != rhs); }
    434 
    435 protected:
    436   int decimals = 0;
    437   LL sum_has_carry(const BNI &a, const BNI &b, BNI &sum) const {
    438     int max_len = max_(a.size(), b.size());
    439     sum = a + b;
    440     if (sum.size() > max_len) { sum.left_shift(); return 1LL; }
    441     return 0LL;
    442   }
    443   BNF join_inte_frac(const BNI &inte, const BNI &frac) const {
    444     return BNF(inte.c_str() + "." + frac.c_str());
    445   }
    446   string clean_tail_zero_str(const string &s) {
    447     int i = 0;
    448     string r;
    449     while (i < s.size() && '.' != s[i]) r += s[i++];
    450 
    451     int j = s.size() - 1;
    452     while (j >= 0 && '0' == s[j]) --j;
    453     for (int k = i + 1; k <= j; ++k) r += s[k];
    454     decimals = j >= i ? j - i : 0;
    455     return r;
    456   }
    457   string clean_zero_str(const string &s) {
    458     string r = BNI::clean_zero_str(s);
    459     return clean_tail_zero_str(r);
    460   }
    461   string c_str() const {
    462     string s;
    463     for (int i = 0; i < num.size(); ++i) {
    464       if (i == decimals) s = '.' + s;
    465       s = char(num[i] + '0') + s;
    466     }
    467     if (s.empty()) s = "0";
    468     if (num.size() == decimals) s = '.' + s;
    469     return s;
    470   }
    471   pair<string, string> split() const {
    472     string s = c_str();
    473     size_t p = s.find('.');
    474     return make_pair(s.substr(0, p), s.substr(p + 1));
    475   }
    476 };
    477 
    478 ostream &operator<<(ostream &out, const BNF &x) {
    479   cout << x.c_str(); return out;
    480 }
    481 
    482 istream &operator>>(istream &in, BNF &x) {
    483   x = BNF(in); return in;
    484 }
    485 
    486 // Trie Tree
    487 const int ALPHASIZE = 26;
    488 
    489 class TrieNode {
    490 public:
    491   TrieNode()
    492     :wordEnd{false}, cnt{1}
    493   {
    494     REP(i, ALPHASIZE) { child[i] = nullptr; }
    495   }
    496   ~TrieNode() {}
    497   void insert(string word) {
    498     int i;
    499     TrieNode *cur = this;
    500     for (auto x:word) {
    501       i = x - 'a';
    502       if (nullptr == cur->child[i]) {
    503         cur->child[i] = new TrieNode();
    504         cur = cur->child[i];
    505       } else {
    506         cur = cur->child[i];
    507         ++cur->cnt;
    508       }
    509     }
    510     cur->wordEnd = true;
    511   }
    512   bool search(string word) {
    513     int i;
    514     TrieNode *cur = this;
    515     for (auto x:word) {
    516       i = x - 'a';
    517       if (nullptr == cur->child[i]) {
    518         return false;
    519       }
    520       cur = cur->child[i];
    521     }
    522     return cur->wordEnd;
    523   }
    524   int cnt_words(string word) {
    525     int i; TrieNode *cur = this;
    526     for(auto x:word) {
    527       i = x - 'a';
    528       if (nullptr == cur->child[i]) return 0;
    529       cur = cur->child[i];
    530     }
    531     return cur->cnt;
    532   }
    533   TrieNode *child[ALPHASIZE];
    534   bool wordEnd;
    535   int cnt; // number of words with the prefix
    536 };
    537 
    538 
    539 
    540 // ==================================================
    541 
    542 
    543 // accepted version 3
    544 
    545 class Solution {
    546 public:
    547     int maxScoreSightseeingPair(vector<int>& A) {
    548       // A.size() >= 2
    549       int res=A[1]+A[0]-1, tmp=A[0];
    550       REP_1(i, A.size()-1) {
    551         res=max_(res,tmp+A[i]-i);
    552         tmp=max_(tmp,A[i]+i);
    553       }
    554       return res;
    555     }
    556 };
    557 
    558 int main( void ) {
    559 
    560 #ifdef DEBUG
    561   freopen("c.in", "r", stdin);
    562 #endif
    563 
    564   Solution sol;
    565   int x; VI a;
    566   while (cin>>x) {
    567     a.push_back(x);
    568   }
    569   PRCO(a);
    570   PRLN(sol.maxScoreSightseeingPair(a));
    571 
    572   return 0;
    573 }
    ヾ<(≧奋≦)>〃

    end.

  • 相关阅读:
    leetcode 576. Out of Boundary Paths 、688. Knight Probability in Chessboard
    leetcode 129. Sum Root to Leaf Numbers
    leetcode 542. 01 Matrix 、663. Walls and Gates(lintcode) 、773. Sliding Puzzle 、803. Shortest Distance from All Buildings
    leetcode 402. Remove K Digits 、321. Create Maximum Number
    leetcode 139. Word Break 、140. Word Break II
    leetcode 329. Longest Increasing Path in a Matrix
    leetcode 334. Increasing Triplet Subsequence
    leetcode 403. Frog Jump
    android中webView加载H5,JS不能调用问题的解决
    通过nginx中转获取不到IP的问题解决
  • 原文地址:https://www.cnblogs.com/algouage/p/10598424.html
Copyright © 2011-2022 走看看