zoukankan      html  css  js  c++  java
  • AtCoder Regular Contest 105 C

    题目链接
    题目描述
    有n只骆驼过m桥,第i只骆驼负重(w_i),第i座桥的长度为(l_i),最大负重为(v_i),问骆驼队伍长度最短为多少可以通过所有的桥。
    思路
    n的数据范围很小,可以暴力解决。根据桥的长度从大到小预处理一下其能承受的重量。
    (dp[i])表示从第一只骆驼到第i只骆驼的最短距离。
    (dp[i] = max(dp[j] + len, dp[i])),len表示第j只骆驼到第i只骆驼的最短距离。寻找len的过程中就是在预处理的桥中二分一下第j只到第i只骆驼的重量所返回的最短桥的长度。
    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    #define int LL
    const int N = 1e5 + 10;
    
    int w[10];
    bool vis[10];
    int b[10], s[10], dp[10];
    struct node {
        int l, v;
        friend bool operator < (node a, node b) {
            if(a.l == b.l) {
                return a.v < b.v;
            }
            return a.l < b.l;
        }
    }a[N];
    int n, m;
    LL res;
    
    int find(int x) {
        int l = 1, r = m;
        int res = 0;
        while(l <= r) {
            int mid = l + r >> 1;
            if(x > a[mid].v) {
                res = a[mid].l;
                l = mid + 1;
            } else r = mid - 1;
        }
        return res;
    }
    
    void work() {
        memset(dp, 0, sizeof dp);
        for(int i = 1; i <= n; i++) {
            s[i] = s[i - 1] + w[b[i]];
        }
        for(int i = 2; i <= n; i++) {
            for(int j = i - 1; j; j--) {
                int tmp = s[i] - s[j - 1];
                int len = find(tmp);
                dp[i] = max(dp[i], dp[j] + len);
            }
        }
        res = min(res, dp[n]);
    }
    
    void dfs(int cnt) {
        if(cnt == n) {
            work();
            return;
        }
        for(int i = 1; i <= n; i++) {
            if(!vis[i]) {
                vis[i] = true;
                b[cnt + 1] = i;
                dfs(cnt + 1);
                vis[i] = false;
            }
        }
    }
    
    void solve() {
        scanf("%lld%lld", &n, &m);
        for(int i = 1; i <= n; i++) {
            scanf("%lld", &w[i]);
        }
        for(int i = 1; i <= m; i++) {
            scanf("%lld%lld", &a[i].l, &a[i].v);
        }
        sort(a + 1, a + 1 + m);
        int mn = 1e9;
        for(int i = m; i >= 1; i--) {
            mn = min(mn, a[i].v);
            a[i].v = mn;
        }
        for(int i = 1; i <= n; i++) {
            if(mn < w[i]) {
                puts("-1");
                return;
            }
        }
        res = 2e18;
        dfs(0);
        printf("%lld
    ", res);
    }
    
    signed main() {
    //    freopen("in.txt", "r", stdin);
    //    int t; scanf("%d", &t); while(t--)
        solve();
    }
    
    
  • 相关阅读:
    Python数据抓取(3) —抓取标题、时间及链接
    Python数据抓取(2) —简单网络爬虫的撰写
    Python数据抓取(2) —简单网络爬虫的撰写
    Apache 显示网页
    Linux 启动 Apache 时报错:(98)Address already in use: make_sock: could not bind to address [::]:80
    Shell编程 之 条件判断式语句
    Shell编程 之 字符处理命令
    Shell编程 之 字符截取命令
    Shell编程 之 正则表达式
    Shell编程 之 环境变量配置文件
  • 原文地址:https://www.cnblogs.com/ZX-GO/p/13810096.html
Copyright © 2011-2022 走看看