【同余最短路】P3403+P2371+P2662+牛客4853D

同余最短路经典套路

给定 n n n个数,每个数都可以选多次(也可以不选),将所有选中的数相加。问最终能够组成多少种不同的数或者不能组成的最大数或者。。。
形如 a x + b y + c z + . . = k ax+by+cz+..=k ax+by+cz+..=k,其中 a , b , c a,b,c a,b,c表示对应的数的选中次数。
从最简单的 a x + b y = k ax+by=k ax+by=k入手分析:
b y = k − a x by=k-ax by=kax b y % x ∈ [ 0 , x − 1 ] by\%x \in{[0,x-1]} by%x[0,x1] i ⇒ ( i + y ) % x , c o s t = y , i ∈ [ 0 , x − 1 ] i\Rightarrow(i+y)\%x,cost=y,i\in{[0,x-1]} i(i+y)%x,cost=y,i[0,x1]
也就是说由 b y by by组成的值对 x x x取余,可以将这些值根据余数分为 x x x组,也就是同余类。并且从余数 i i i到余数 ( i + y ) % x (i+y)\%x (i+y)%x的代价是 y y y
建图,边的信息为 ( i , ( i + y ) % x , y ) , i ∈ [ 0 , x − 1 ] (i, (i+y)\%x, y), i\in{[0,x-1]} (i,(i+y)%x,y),i[0,x1],表示从点 i i i到点 ( i + y ) % x (i+y)\%x (i+y)%x的代价是 y y y(当然也存在 b y % x ≠ i by\%x\ne i by%x=i这种情况)。
d i s [ i ] dis[i] dis[i]表示满足 b y % x = i by\%x=i by%x=i的最小的 b y by by,也就是最少要选取 b b b y y y,才能使 b y % x = i , b ≥ 0 by\%x=i,b≥0 by%x=i,b0,也就是每个同余类中的最小值。
d i s [ ] dis[] dis[]就相当于在图中求最短路(我习惯用spfa),且 d i s [ 0 ] = 0 dis[0]=0 dis[0]=0(因为 0 ∗ y % x = 0 0*y\%x=0 0y%x=0
求完 d i s [ i ] dis[i] dis[i]之后便得到了每个同余类中的最小值 p i p_i pi,很明显 p i + x p_i+x pi+x p i p_i p

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值