搜索:https://www.cnblogs.com/SiriusRen/p/6532506.html?tdsourcetag=s_pctim_aiomsg 來自 SiriusRen
數據範圍小,考慮直接dfs,剪枝:到達此層如果用時更長就不再搜了,
然而我有一個問題就是到達每層手柄的狀態並不一樣,怎麼能直接更新呢?
然而我用二維的寫掛了,T5個點,所以先放上一維的掛著了......
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,m,c[22],ans=0x7fffffff,p; int time[1005]; int abs(int a){return a<0?-a:a;} void dfs(int fl,int t,int pos) { if(fl==n)ans=min(ans,t); for(int i=1;i<=m;i++){ int x=fl+c[i];if(x<=0 || x>n)continue; int tt=t+abs(pos-i)+2*abs(c[i]); if(time[x]<=tt)continue; time[x]=tt; dfs(x,tt,i); } } int main() { memset(time,0x3f,sizeof(time)); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d",&c[i]);if(c[i]==0)p=i; } for(int i=1;i<=n;i++)time[i]=0x7fffffff; dfs(1,0,p); if(ans!=0x7fffffff) printf("%d",ans); else printf("-1"); }
如果考慮最短路,可以跑一次spfa,在隊列裡維護當前樓層和手柄位置,其實相當於廣搜,掛了層最短路的皮而已
然而我考試時竟然最後更新ans時寫的 for(1...m)ans=min(ans,d[n][m]).............狗屎
別忘了判-1......
#include<iostream> #include<cstdio> #include<algorithm> #include<queue> #include<cstring> #define mp make_pair using namespace std; const int maxn=1005; queue<pair<int,int> >q; int n,m,pos; int c[22]; int d[maxn][22],v[maxn][22]; int main() { freopen("up.in","r",stdin); freopen("up.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d",&c[i]);if(c[i]==0)pos=i; } memset(d,0x3f,sizeof(d)); q.push(mp(1,pos)); v[1][pos]=1;d[1][pos]=0; while(!q.empty()){ int x=q.front().first,y=q.front().second;q.pop(); v[x][y]=0; for(int i=1;i<=m;i++){ int yy=x+c[i],dd=(abs(i-y)+2*abs(c[i])); if(yy<=0 || yy>n)continue; if(d[yy][i]>d[x][y]+dd){ d[yy][i]=d[x][y]+dd; if(!v[yy][i])q.push(mp(yy,i)),v[yy][i]=1; } } } int ans=0x3f3f3f3f; for(int i=1;i<=m;i++) ans=min(ans,d[n][i]); if(ans!=0x3f3f3f3f) printf("%d",ans); else printf("-1"); fclose(stdin);fclose(stdout); }