zoukankan      html  css  js  c++  java
  • 洛谷 P2662 牛场围栏 (同余最短路)

    题目:传送门

    题意

    小L有N种可以建造围栏的木料,长度分别是l1,l2 … lN,每种长度的木料无限。任何一根木料最多只能削短M米,修建时,他将把所有选中的木料拼接在一起,因此围栏的长度就是他使用的木料长度之和。问不能修建的围栏长度最大是多少,若任何长度的围栏都能修建,就输出 -1,或者不能修建的这个最大值不存在(也就是无穷大)也输出 -1.

    1 < N < 100, 0 < M < 3000

    思路

    考虑输出 -1 的情况:

    ①:若某根木棒长度等于 1 或者削短后等于 1,那么所有的长度都能被表示出来,那就输出 -1.

    ②:若 gcd({l1, l1 - 1,.... l1 - m, l2,..... l2 - m, … lN, ..... lN - m}) > 1,也就是所有数的 gcd 都大于 1,那么不能被表示的是无穷大的,我们设 q 为所有数的 gcd,那么任意 % q != 0 的长度都不能被修建,显然这个数是无穷大的。

    剩下的就是有解的情况。

    我们设 dis[i] 表示由 n 种木棒和他们削短 1 ~ m 之后的木棒中选定一些能凑出来的 % (min({l1, l2, l3 .. lN}-m) 等于 i 的最小的数,那最大不能建成的就是 max{dis[i] - ( min(l1,l2..lN) - m ) } 。

     

    #include <bits/stdc++.h>
    #define LL long long
    #define ULL unsigned long long
    #define mem(i, j) memset(i, j, sizeof(i))
    #define rep(i, j, k) for(int i = j; i <= k; i++)
    #define dep(i, j, k) for(int i = k; i >= j; i--)
    #define pb push_back
    #define make make_pair
    #define INF INT_MAX
    #define inf LLONG_MAX
    #define PI acos(-1)
    #define fir first
    #define sec second
    using namespace std;
    
    const int N = 2500010;
    const LL mod = 1e9 + 7;
    
    int n, m, a[500], dis[N << 1], vis[N << 1], tot;
    int fir[N], nx[N << 1], to[N << 1], cost[N << 1];
    
    void add(int u, int v, int w) {
        nx[++tot] = fir[u];
        fir[u] = tot;
        to[tot] = v;
        cost[tot] = w;
    }
    
    void spfa() {
        queue < int > q;
        mem(dis, 0x3f3f3f3f);
        mem(vis, 0);
        vis[0] = 1;
        dis[0] = 0;
        q.push(0);
        while(!q.empty()) {
            int u = q.front();
            q.pop();
            vis[u] = 0;
            for(int e = fir[u]; e; e = nx[e]) {
                int v = to[e], w = cost[e];
                if(dis[v] > dis[u] + w) {
                    dis[v] = dis[u] + w;
                    if(!vis[v]) {
                        q.push(v);
                        vis[v] = 1;
                    }
                }
            }
        }
    }
    
    int main() {
    
        scanf("%d %d", &n, &m);
    
        rep(i, 1, n) scanf("%d", &a[i]);
    
        sort(a + 1, a + 1 + n);
    
        if(a[1] - m <= 1) {
            puts("-1");
            return 0;
        }
    
        rep(i, 1, n) {
            rep(j, max(a[i] - m, a[i - 1] + 1), a[i]) {
                rep(k, 0, a[1] - m - 1) {
                    add(k, (k + j) % (a[1] - m), j);
                }
            }
        }
    
        spfa();
    
        int ans = 0;
    
        rep(i, 1, a[1] - m - 1) {
            if(dis[i] > 100000000) {
                puts("-1");
                return 0;
            }
            ans = max(ans, dis[i] - (a[1] - m));
        }
        printf("%d
    ", ans);
        return 0;
    }
    一步一步,永不停息
  • 相关阅读:
    修复 Visual Studio Error “No exports were found that match the constraint”
    RabbitMQ Config
    Entity Framework Extended Library
    Navisworks API 简单二次开发 (自定义工具条)
    NavisWorks Api 简单使用与Gantt
    SQL SERVER 竖表变成横表
    SQL SERVER 多数据导入
    Devexpress GridControl.Export
    mongo DB for C#
    Devexress XPO xpPageSelector 使用
  • 原文地址:https://www.cnblogs.com/Willems/p/12622363.html
Copyright © 2011-2022 走看看