zoukankan      html  css  js  c++  java
  • luogu P2662 牛场围栏

    传送门

    因为一个木板可以切掉最多(m),所以可以先预处理哪些长度的木板可用,开个桶,然后对([l-m,l])打标记,再把打了标记的数取出来

    假设可用长度(a_1,a_2,,,a_n)从小到大排好了序,我们可以先不用(a_1),只用后面的长度拼,然后用(a_1)凑,所以设(di_i)为能用后面的凑出的并且(mod a_1)(i)的最短长度((di_0=0)),然后可以把(a_2,,,a_n)当做从位置(i)连向((i+a_j)mod a_1),边权为(a_j)的边,跑个最短路就可以求出所有(di)

    最后答案为(max_{i=0}^{a_1-1}di_i-a_1),因为这些长度(d_i)没有用(a_1)拼出来,这里面任何一个长度减(a_1)就是不能拼出的长度

    注意判无解

    #include<bits/stdc++.h>
    #define LL long long
    #define il inline
    #define re register
    
    using namespace std;
    const int N=3000+10,M=N*N;
    il LL rd()
    {
        re LL x=0,w=1;re char ch;
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    int to[M],nt[M],w[M],hd[N],tot=1;
    il void add(int x,int y,int z) {++tot,to[tot]=y,nt[tot]=hd[x],w[tot]=z,hd[x]=tot;}
    struct node
    {
      int x,d;
      bool operator < (const node &b) const {return d>b.d;}
    };
    int n,m,a[N],di[N];
    short vv[N];
    il int gcd(int a,int b){return b?gcd(b,a%b):a;}
    
    int main()
    {
      n=rd(),m=rd();
      while(n--)
        {
          int x=rd();
          ++vv[max(1,x-m)],--vv[x+1];
        }
      n=0;
      for(int i=1;i<=N-10;i++)
        {
          vv[i]+=vv[i-1];
          if(vv[i]>0) a[++n]=i;
        }
      int gg=a[1];
      for(int i=2;i<=n;i++) gg=gcd(gg,a[i]);
      if(gg>1||a[1]==1) {puts("-1");return 0;}  //判无解
      for(int i=0;i<a[1];i++)
        for(int j=2;j<=n;j++)
          add(i,(i+a[j])%a[1],a[j]);
      memset(di,63,sizeof(di));
      di[0]=0;
      priority_queue<node> q;
      q.push((node){0,0});
      while(!q.empty())
        {
          int x=q.top().x,d=q.top().d;
          q.pop();
          if(d>di[x]) continue;
          for(int i=hd[x];i;i=nt[i])
            {
              int y=to[i];
              if(di[y]>di[x]+w[i])
                {
                  di[y]=di[x]+w[i];
                  q.push((node){y,di[y]});
                }
            }
        }
      int ans=a[1];
      for(int i=0;i<a[1];i++) ans=max(ans,di[i]);
      printf("%d
    ",ans-a[1]);
      return 0;
    }
    
    
  • 相关阅读:
    thymeleaf时间戳转换
    alerttemplate 时间戳转换
    jQuery.Deferred exception: a.indexOf is not a function TypeError: a.indexOf is not a function
    区分数据是对象还是字符串
    eclipse中选取一列快捷键
    图片拉伸不变型
    这里ajax需要改成同步
    idea如何整理代码格式
    20170311-起早床
    20190310-解决头屑
  • 原文地址:https://www.cnblogs.com/smyjr/p/9739391.html
Copyright © 2011-2022 走看看