AtCoder - ARC105_C Camels and Bridge (dp + 二分)

Problem Statement

 

There are NN camels numbered 11 through NN.

The weight of Camel ii is wiwi.

You will arrange the camels in a line and make them cross a bridge consisting of MM parts.

Before they cross the bridge, you can choose their order in the line - it does not have to be Camel 11, 22, ……, NN from front to back - and specify the distance between each adjacent pair of camels to be any non-negative real number. The camels will keep the specified distances between them while crossing the bridge.

The ii-th part of the bridge has length lili and weight capacity vivi. If the sum of the weights of camels inside a part (excluding the endpoints) exceeds vivi, the bridge will collapse.

Determine whether it is possible to make the camels cross the bridge without it collapsing. If it is possible, find the minimum possible distance between the first and last camels in the line in such a case.

It can be proved that the answer is always an integer, so print an integer.

Constraints

 

  • All values in input are integers.
  • 2≤N≤82≤N≤8
  • 1≤M≤1051≤M≤105
  • 1≤wi, li, vi≤1081≤wi, li, vi≤108

Input

 

Input is given from Standard Input in the following format:

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

Output

 

If the bridge will unavoidably collapse when the camels cross the bridge, print -1. Otherwise, print the minimum possible distance between the first and last camels in the line when the camels cross the bridge without it collapsing.

Sample Input 1

 

3 2
1 4 2
10 4
2 6

Sample Output 1

 

10
  • It is possible to make the camels cross the bridge without it collapsing by, for example, arranging them in the order 11, 33, 22 from front to back, and setting the distances between them to be 00, 1010.
    • For Part 11 of the bridge, there are moments when only Camel 11 and 33 are inside the part and moments when only Camel 22 is inside the part. In both cases, the sum of the weights of camels does not exceed 44 - the weight capacity of Part 11 - so there is no collapse.
    • For Part 22 of the bridge, there are moments when only Camel 11 and 33 are inside the part and moments when only Camel 22 is inside the part. In both cases, the sum of the weights of camels does not exceed 66 - the weight capacity of Part 22 - so there is no collapse.
  • Note that the distance between two camels may be 00 and that camels on endpoints of a part are not considered to be inside the part.

Sample Input 2

 

2 1
12 345
1 1

Sample Output 2

 

-1
  • Print -1 if the bridge will unavoidably collapse.

Sample Input 3

 

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

Sample Output 3

 

700000000

Sample Input 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

Sample Output 4

 

3802

Title:

Existing n camels lined up across m consecutive bridges, given the weight of each camel, the maximum load-bearing capacity and length of each bridge, find the shortest distance from the first camel to the nth camel, the order of the camels lined up can be change.

Ideas:

dp[i] Represents the shortest distance from the i-th camel to the first camel, and the transfer equation:dp[i] = max(dp[i], dp[j] + len)

len represents the shortest distance that the j-th camel to the i-th camel can safely cross the bridge and need to be maintained

-------------------------------------------------- --------------------
Q: Why take max?

A: It dp[j] + len is only guaranteed that the camels j~i can safely cross the bridge. To make all the camels can cross the bridge safely, the maximum value of the shortest distance must be taken

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

Find len in two points.

Preparation: Sort all bridges according to the length of the first keyword and the bearing of the second keyword. Bridges with very long length and small load-bearing limit the load-bearing capacity of bridges with very short length and large load-bearing. The load-bearing capacity of the bridge is modified to the minimum load-bearing capacity of the longer bridge.

Divide the shortest distance, check whether the load-bearing capacity of the current bridge is> the total weight of the j-th ~ i-th camel, and return to the shortest bridge that can accommodate these camels

#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;
}

 

Guess you like

Origin blog.csdn.net/weixin_43871207/article/details/109190106