洛谷P3943星空
啦啦啦啦——又是五月天的歌,题目传送门
这道题比之前两道真的不是同一级别的,这里我这个蒟蒻也讲不清,不如看下这位大佬的吧,他的写的已经非常清楚了:Z-Y-Y-S,这里我就只放下我的代码,也是按照这位大佬的思路做的:
#include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<cstdlib> #include<iostream> #include<algorithm> #define N 50005 using namespace std; typedef long long ll; ll f[1<<18+1],dis[N],len[105],cost[105][105]; int a[N],b[N],s[N],n,m,k,cnt;queue<int>team; inline int read() { char ch=getchar();int num=0;bool flag=false; while(ch<'0'||ch>'9'){if(ch=='-')flag=true;ch=getchar();} while(ch>='0'&&ch<='9'){num=num*10+ch-'0';ch=getchar();} return flag?-num:num; } void BFS() { for(int i=1;i<=cnt;i++){ memset(dis,-1,sizeof(dis)); while(!team.empty())team.pop(); team.push(s[i]);dis[s[i]]=0; while(!team.empty()){ int u=team.front(); team.pop(); for(int j=1;j<=m;j++){ for(int l=-1;l<=1;l+=2){ int v=u+l*len[j]; if(v>=1&&v<=n&&dis[v]==-1){ dis[v]=dis[u]+1; if(b[v])cost[i][b[v]]=dis[v]; team.push(v); } } } } } } void ready() { n=read();k=read();m=read(); for(int i=1;i<=k;i++)a[read()]=1; n++; for(int i=1;i<=n;i++)b[i]=a[i]^a[i-1]; for(int i=1;i<=n;i++) if(b[i]){b[i]=++cnt;s[cnt]=i;} for(int i=1;i<=m;i++)len[i]=read(); BFS(); } void work() { memset(f,127/3,sizeof(f)); f[0]=0; for(int i=0;i<=(1<<cnt)-1;i++){ for(int j=2;j<=cnt;j++) if((i&(1<<j-1))==0){ for(int k=1;k<=j-1;k++) if((i&(1<<k-1))==0){ if(cost[j][k]){ int v=i|(1<<j-1); v|=(1<<k-1); f[v]=min(f[v],f[i]+cost[j][k]); } } } } printf("%lld",f[(1<<cnt)-1]); } int main() { ready(); work(); return 0; }
蒟蒻写博客不易,如果有误还请大佬们提出
如需转载,请署名作者并附上原文链接,蒟蒻非常感激
名称:HolseLee
博客地址:www.cnblogs.com/cytus
个人邮箱:1073133650@qq.com
如需转载,请署名作者并附上原文链接,蒟蒻非常感激
名称:HolseLee
博客地址:www.cnblogs.com/cytus
个人邮箱:1073133650@qq.com