標籤:pre max 資料規模 ble print www. 難題 暴力 cpp
題面
著名的TSP問題,NPC問題
對於資料大的情況,我們可以使用一系列近似演算法進行尋找解。
對於資料規模小的情況,我們可以直接暴力dp
一開始寫了一個dfs,然後就被n=20的數據卡爆了
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using std::min;const int maxn=22;int f[1<<maxn][maxn];int M[maxn][maxn];int n;int dfs(int base,int now){ if(base&1==0) return f[base][now]=0x7fffffff; if(f[base][now]) return f[base][now]; int ans=0x7ffffff; for(int i=0;i<n;i++) if(base&(1<<i)&&i+1!=now) ans=min(ans,dfs(base^(1<<(now-1)),i+1)+M[i+1][now]); return f[base][now]=ans;}int main(){ scanf("%d",&n); f[1][1]=1; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { scanf("%d",&M[i][j]); if(i==j) M[i][j]=0x7ffffff; } for(int i=1;i<=n;i++) { M[i][n+1]=M[i][1]; M[n+1][i]=M[1][i]; } n++; dfs((1<<n)-1,n); printf("%d",f[(1<<n)-1][n]-1);}
然後就回去補了一發遞推,還是遞推常數小呀。
#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>using std::min;const int maxn=20,inf=0x7ffffff;int f[1<<maxn][maxn];int M[maxn][maxn];int n;int main(){ memset(f,127,sizeof(f)); scanf("%d",&n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf("%d",&M[i][j]); for(int i=0;i<n;i++) M[i][i]=inf; f[1][0]=0; for(int i=1;i<(1<<n);i++) for(int j=0;j<n;j++) if(i&(1<<j)) for(int k=0;k<n;k++) if((i&(1<<k))==0) f[i^(1<<k)][k]=min(f[i^(1<<k)][k],f[i][j]+M[j][k]); int ans=inf; for(int i=1;i<n;i++) ans=min(ans,f[(1<<n)-1][i]+M[i][0]); printf("%d",ans);}
感覺dp在noip會是我的大難♂題
P1171 售貨員的難題 暴力dp