luogu P1171 售貨員的難題
阿新 • • 發佈:2017-10-19
name 代碼 true span turn str %d 說明 -s
題目背景
數據有更改
題目描述
某鄉有n個村莊(1<n<20),有一個售貨員,他要到各個村莊去售貨,各村莊之間的路程s(0<s<1000)是已知的,且A村到B村與B村到A村的路大多不同。為了提高效率,他從商店出發到每個村莊一次,然後返回商店所在的村,假設商店所在的村莊為1,他不知道選擇什麽樣的路線才能使所走的路程最短。請你幫他選擇一條最短的路。
輸入輸出格式
輸入格式:
村莊數n和各村之間的路程(均是整數)。
輸出格式:
最短的路程。
輸入輸出樣例
輸入樣例#1:3
0 2 1
1 0 2
2 1 0
輸出樣例#1:3
說明
輸入解釋
3 {村莊數}
0 2 1 {村莊1到各村的路程}
1 0 2 {村莊2到各村的路程}
2 1 0 {村莊3到各村的路程}
題目鏈接:https://www.luogu.org/problem/show?pid=1171#sub
解題報告
傻逼狀壓DP,沒了!!!
AC代碼
#include<cstdio> #include<iostream> #include<vector> #include<algorithm> #define INF (1<<28) #define FOR(i,s,t) for(register int i=s;i<=t;++i) using namespace std; int f[1<<20][20]; int one[20]; int zero[20]; int r[21][21]; int n,ans,m,o,z; inline int min(int x,int y){ return x<y?x:y; } int main(){ scanf("%d",&n); FOR(i,0,n-1) FOR(j,0,n-1) scanf("%d",&r[i][j]); m=(1<<n)-1; FOR(i,0,m) FOR(j,0,n-1) f[i][j]=INF; f[1][0]=0; for(register int i=1;i<=m;i+=2){ one[0]=zero[0]=0; FOR(j,0,n-1) i&(1<<j)?one[++one[0]]=j:zero[++zero[0]]=j; FOR(k,1,one[0]) FOR(j,1,zero[0]){ o=one[k]; z=zero[j]; f[i|(1<<z)][z]=min(f[i|(1<<z)][z],f[i][o]+r[o][z]); } } ans=INF; FOR(i,1,n-1) ans=min(ans,f[m][i]+r[i][0]); cout<<ans<<endl; return 0; }
luogu P1171 售貨員的難題