同余类bfs(其实之前我是用可行性dp卡过去的),个人理解就是按最小值为模数取模后跑到达每一个余数的最短路。
#include<bits/stdc++.h>
using namespace std;
int n,m,mo,dis[3010];
bool vis[3010],inq[3010];
vector<int>tax;
void spfa()
{
int nw,v,ans=0;
queue<int>q;
memset(dis,127,sizeof dis);
dis[0]=0,q.push(0),inq[0]=1;
while(!q.empty())
{
nw=q.front(),q.pop();
for(int i=0;i<tax.size();i++)
{
v=(tax[i]+nw)%mo;
if(dis[v]>dis[nw]+tax[i])
{
dis[v]=dis[nw]+tax[i];
if(!inq[v])q.push(v);
inq[v]=1;
}
}
inq[nw]=0;
}
for(int i=0;i<mo;i++)
ans=max(ans,dis[i]-mo);
(ans>1e9||ans==0)?puts("-1"):printf("%d\n",ans);
}
int main()
{
int tmp;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&tmp);
for(int j=0;j<=m&&j<tmp;j++)
vis[tmp-j]=1;
}
for(int i=1;i<=3000;i++)
if(vis[i])tax.push_back(i);
mo=tax[0];
spfa();
}