当前位置: 首页 > news >正文

题解:P2662 牛场围栏

省流:同余最短路

本题是一道同余最短路算法的好题。接下来讲讲个人对这道题的理解。

首先,根据题意,我们知道,我们可以获得最多 \(m \times (m +1)\) 种木棍长度。我们设 \(t\) 为这个最大值,则木棍长度可表示为 \(a_1,a_2,…,a_t\)。设栅栏长度为 \(l\) ,若一个栅栏的长度是可表示的,则等同于 \(\exist k_1,k_2,…,k_t\in\Z^+,k_1a_1+k_2a_2+…+k_ta_t=l\)

根据数据范围可以看到,\(t\) 最大可以达到 \(9000000\),因此直接爆搜肯定不现实。但我们发现,单个木棍的长度最长只有 \(100\),我们又发现,当其中 \(t-1\) 个系数确定后,所有可表示的栅栏长度对剩下那个未被确定的系数对应的木棍长度取余的结果相同。因此,我们就可以使用同余的思想,选取长度最小的木棍来作为系数不确定的木棍,设其长度为 \(a_1\),同时设 \(d_i(i\in[0,a_1-1])\) 来表示当 \(l \bmod a_1=i\) 时,\(l\) 的最小值。此时,我们只需要建立从 $i(i\in[0,a_1-1]) $ 到 \((a_j+i)\bmod a_1(j\in[1,t])\),长度为 \(a_j\) 的有向边,并跑一遍 Dijkstra 求最短路即可。

在求出最短路后,若 \(d_i(i\in[0,a_1-1])\) 未被更新,就说明不存在最大值,输出 \(-1\)。否则,求出 \(ans=max\set{d_i-a_1(i\in[0,a_1-1])}\),输出即可。

上代码

#include<bits/stdc++.h>
using namespace std;#define int long longconst int N=3005;
const int M=6000005;int n,m;
int ans=-1,tot,maxn,minn=0x7ffffff;
int l[N],h[N];
int edge[M],ver[M],head[M],Next[M];
int d[M],vis[M];struct node{int id,step;bool operator <(const node b)const{return step>b.step;}
};priority_queue<node>q;inline int read(){int f=1,k=0;char c=getchar();while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}while(c>='0'&&c<='9'){k=k*10+c-'0';c=getchar();}return f*k;
}void add(int x,int y,int z){edge[++tot]=z; ver[tot]=y; Next[tot]=head[x]; head[x]=tot;
}void dij(){d[0]=0;q.push(node{0,0});while(!q.empty()){int x=q.top().id; q.pop();if(vis[x]) continue;		vis[x]=true;for(int i=head[x];i;i=Next[i]){int y=ver[i];int z=edge[i];if(d[y]>d[x]+z){d[y]=d[x]+z;q.push(node{y,d[y]});}}}
}signed main(){n=read(),m=read();for(int i=1;i<=n;i++) l[i]=read();for(int i=1;i<=n;i++){for(int j=l[i]-m;j<=l[i];j++) h[j]=1;maxn=max(l[i],maxn);minn=min(l[i]-m,minn); //求出木棍长度、最小值和最大值}for(int i=0;i<minn;i++){for(int j=minn;j<=maxn;j++)if(h[j]==1) add(i,(i+j)%minn,j); //加边d[i]=(1ull<<63)-1;}dij();for(int i=0;i<minn;i++){if(d[i]==(1ull<<63)-1){cout<<-1<<endl;return 0;}ans=max(ans,d[i]-minn);}cout<<ans<<endl;return 0;
}
```1. 
http://www.rkmt.cn/news/11936.html

相关文章:

  • c语言初步学习
  • Cloudflare安全验证过程全解析
  • 【网络编程】UDP 编程实战:从套接字到聊天室多场景计划构建
  • week1 homework
  • Java EE ----- Spring MVC (上) - 实践
  • window.addEventListener(message,()={})中的回调函数无故被一直触发的问题 - broky
  • python+pillow+Image实现图片压缩到指定大小
  • 3D 高斯训练速度和消耗 - MKT
  • 完整教程:【PyTorch实战:文本分类】23、BERT文本分类实战指南:从原理到PyTorch落地
  • proxifier联合burpsuite抓包小程序,但是小程序连不上网解决办法(亲测)
  • 完整教程:C语言——函数(超详细分析)
  • 用 Swift 和 Tesseract OCR 实现验证码识别
  • 校园交友|基于SprinBoot+vue的校园交友网站(源码+数据库+文档) - 实践
  • 告别单张保存!PPT 图片无损批量提取,这 3 种方法亲测有效!
  • ?模拟赛(2) 赛后总结
  • 【C语言】C语言预处理详解,从基础到进阶的全面讲解 - 指南
  • 掌握C2重定向器:红蓝队攻防实战指南
  • Avalonia:开发Android应用
  • 多GPU本地布署Wan2.2-T2V-A14B文本转视频模型 - yi
  • 软工9.25
  • P8367 [LNOI2022] 盒
  • Polar2025秋季个人挑战赛web-writeup
  • 通过【开题答辩过程】以《基于JavaEE的创意产品众筹平台的设计与实现》为例,不会开题答辩的能够进来看看
  • 如何在CentOS 7上安装bzip2-1.0.6-13.el7.x86_64.rpm RPM包(详细步骤)
  • 2025年Java常见面试题
  • 实用指南:k8s 跟 nacos 关于服务注册以及服务发现
  • AT_agc021_d [AGC021D] Reversed LCS
  • adb shell 常用文件命令
  • 你所不知道的Spring的@Autowired实现细节
  • Java文件编程