AtCoder - ARC105_C Верблюды и мост (dp + 二 分)

Постановка задачи

 

Есть NN верблюдов, пронумерованных с 11 по NN.

Вес Camel II равен wiwi.

Вы разместите верблюдов в линию и заставите их пересечь мост, состоящий из частей ММ.

Перед тем, как они пересекут мост, вы можете выбрать их порядок в строке - он не обязательно должен быть Camel 11, 22, ……, NN спереди назад - и указать расстояние между каждой соседней парой верблюдов, чтобы оно не было любым. отрицательное действительное число. Верблюды будут сохранять заданное расстояние между собой при переходе по мосту.

II часть моста имеет длину lili и грузоподъемность vivi. Если сумма весов верблюдов внутри детали (без учета конечных точек) превышает vivi, мост рухнет.

Определите, можно ли заставить верблюдов перейти мост без его обрушения. Если возможно, найдите минимально возможное расстояние между первым и последним верблюдами в очереди в таком случае.

Можно доказать, что ответ всегда целое число, поэтому выведите целое число.

Ограничения

 

  • Все входные значения - целые числа.
  • 2≤N≤82≤N≤8
  • 1≤M≤1051≤M≤105
  • 1≤wi, li, vi≤1081≤wi, li, vi≤108

Вход

 

Ввод осуществляется из стандартного ввода в следующем формате:

NN MM
w1w1 w2w2 ⋯⋯ wNwN
l1l1 v1v1
⋮⋮
lMlM vMvM

Выход

 

Если мост неизбежно рухнет, когда верблюды перейдут мост, печатайте  -1. В противном случае выведите минимально возможное расстояние между первым и последним верблюдами в строке, когда верблюды пересекают мост без его обрушения.

Пример ввода 1

 

3 2
1 4 2
10 4
2 6

Пример вывода 1

 

10
  • Можно заставить верблюдов пересекать мост без его обрушения, например, расположив их в порядке 11, 33, 22 спереди назад и установив расстояния между ними равными 00, 1010.
    • Для части 11 моста бывают моменты, когда только Camel 11 и 33 находятся внутри части, и моменты, когда только Camel 22 находится внутри части. В обоих случаях сумма весов верблюдов не превышает 44 - грузоподъемность части 11 - так что разрушения нет.
    • Для части 22 моста бывают моменты, когда только Camel 11 и 33 находятся внутри части, и моменты, когда только Camel 22 находится внутри части. В обоих случаях сумма весов верблюдов не превышает 66 - грузоподъемность части 22 - так что разрушения нет.
  • Обратите внимание, что расстояние между двумя верблюдами может быть 00, и что верблюды на концах детали не считаются находящимися внутри детали.

Пример ввода 2

 

2 1
12 345
1 1

Пример вывода 2

 

-1
  • Печатайте,  -1 если мост неизбежно рухнет.

Пример ввода 3

 

8 1
1 1 1 1 1 1 1 1
100000000 1

Пример вывода 3

 

700000000

Пример ввода 4

 

8 20
57 806 244 349 608 849 513 857
778 993
939 864
152 984
308 975
46 860
123 956
21 950
850 876
441 899
249 949
387 918
34 965
536 900
875 889
264 886
583 919
88 954
845 869
208 963
511 975

Пример вывода 4

 

3802

Заголовок:

Существующие n верблюдов выстроились в линию через m последовательных мостов, учитывая вес каждого верблюда, максимальную несущую способность и длину каждого моста, найдите кратчайшее расстояние от первого верблюда до n-го верблюда, порядок верблюдов, выстроившихся в линию, может измениться.

Идеи:

дп [я] Представляет кратчайшее расстояние от i-го верблюда до первого верблюда и уравнение переноса:dp [i] = max (dp [i], dp [j] + len)

len представляет собой кратчайшее расстояние, которое от j-го до i-го верблюда может безопасно пересечь мост и которое необходимо поддерживать

-------------------------------------------------- -------------------- В
: Зачем брать макс?

О: dp [j] + len Гарантируется только то, что верблюды j ~ i могут безопасно пересечь мост. Чтобы все верблюды могли безопасно пересечь мост, необходимо взять максимальное значение кратчайшего расстояния.

-------------------------------------------------- --------------------

Найдите len в двух точках.

Подготовка: отсортируйте все мосты в соответствии с длиной первого ключевого слова и несущей способностью второго ключевого слова. Мосты очень большой длины и малой нагрузки ограничивают несущую способность мостов небольшой длины и большой несущей способности. Таким образом, непосредственно сортируйте каждый мост перед сортировкой.Несущая способность моста доводится до минимальной несущей способности более длинного моста.

Разделите кратчайшее расстояние, проверьте, превышает ли несущая способность текущего моста общий вес j-го ~ i-го верблюда, и вернитесь к самому короткому мосту, на котором могут разместиться эти верблюды.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N = 1e5 + 10;
const int M = 5e4 + 10;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;

int w[10], res, dp[10], sum[10], n, m, b[10];
bool vis[10];
struct node {
    int w, l;
    bool operator < (const node &a) {
        if(l == a.l) return w < a.w;
        else return l < a.l;
    }
} s[N];

///这俩二分都对
int lower_b(int x) {
    int l = 0, r = m + 1;
    while(l + 1 < r) {
        int mid = (l + r) >> 1;
        if(x > s[mid].w) l = mid;
        else r = mid;
    }
    return s[l].l;
}

//int lower_b(int x) {
//    int l = 1, r = m, res = 0;
//    while(l <= r) {
//        int mid = (l + r) >> 1;
//        if(x > s[mid].w) {
//            res = s[mid].l;
//            l = mid + 1;
//        }
//        else r = mid - 1;
//    }
//    return res;
//}

void solve() {
    memset(dp, 0, sizeof(dp));
    for(int i = 1; i <= n; ++i) sum[i] = sum[i - 1] + w[b[i]];
    for(int i = 2; i <= n; ++i) {
        for(int j = i - 1; j >= 1; --j) {
            int tmp = sum[i] - sum[j - 1];
            int len = lower_b(tmp);
            dp[i] = max(dp[i], len + dp[j]);
        }
    }
    res = min(res, dp[n]);
}

void dfs(int now) {
    if(now == n) {
        solve();
        return ;
    }
    for(int i = 1; i <= n; ++i) {
        if(!vis[i]) {
            vis[i] = 1;
            b[now + 1] = i;
            dfs(now + 1);
            vis[i] = 0;
        }
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++i) scanf("%d", &w[i]);
    for(int i = 1; i <= m; ++i) scanf("%d%d", &s[i].l, &s[i].w);
    sort(s + 1, s + m + 1);
    int minn = inf;
    for(int i = m; i >= 1; --i) {
        minn = min(minn, s[i].w);
        s[i].w = minn;
    }
    for(int i = 1; i <= n; ++i) {
        if(w[i] > minn) {
            printf("-1\n");
            return 0;
        }
    }
    res = inf;
    dfs(0);
    printf("%d\n", res);
    return 0;
}

 

рекомендация

отblog.csdn.net/weixin_43871207/article/details/109190106