[LSGDOJ 1505]售货员的难题 状压DP
2017-05-28 15:54
330 查看
题目描述
某 乡有n个村庄(1<n<15),有一个售货员,他要到各个村庄去售货,各村庄之间的路程s(0<s<1000)是已知的,且A村 到B村与B村到A村的路大多不同。为了提高效率,他从商店出发到每个村庄一次,然后返回商店所在的村,假设商店所在的村庄为1,他不知道选择什么样的路线 才能使所走的路程最短。请你帮他选择一条最短的路。输入
村庄数n和各村之间的路程(均是整数)。输出
最短的路程。样例输入
3 0 2 1 1 0 2 2 1 0样例输出
3题解:
F[i][j],j是状压后的数,是1表示经过,0表示不经过,表示从起点到i经过k1,k2,k3(k&j==1)的村庄的最小路程.
然后就是DP方程
F[j][k|(1<<j-1)]=max(F[i][k]+dis[i][j]) 其中(1<<i-1)&j==1 (1<<j-1)&j==0
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; int gi(){ int str=0;char ch=getchar(); while(ch>'9' || ch<'0')ch=getchar(); while(ch>='0' && ch<='9')str=str*10+ch-48,ch=getchar(); return str; } const int N=15; int n;int dis ;int F [1<<N]; int main() { int x; n=gi();int pp=(1<<n)-1,tmp; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dis[i][j]=gi(); memset(F,127/3,sizeof(F)); F[1][1]=0; for(int k=1;k<=pp;k++) { for(int i=1;i<=n;i++) { if(!((1<<i-1)&k))continue; for(int j=1;j<=n;j++) { if(j==i || (1<<j-1)&k || !dis[i][j])continue; tmp=F[i][k]+dis[i][j]; if(tmp<F[j][k|(1<<j-1)])F[j][k|(1<<j-1)]=tmp; } } } int ans=1999999999; for(int i=2;i<=n;i++) { if(dis[i][1]==0)continue; if(F[i][pp]+dis[i][1]<ans)ans=F[i][pp]+dis[i][1]; } printf("%d",ans); return 0; }
相关文章推荐
- 洛谷 P1171 售货员的难题 【状压dp】
- 洛谷 P1171 售货员的难题 【状压dp】
- 洛谷P1171 售货员的难题【状压DP】
- 售货员难题 状压dp
- 【状压DP】售货员的难题
- 【codevs2596】售货员的难题 状压DP
- 洛谷 1171 售货员的难题 状压DP 解题报告
- 售货员的难题
- Luogu 1171 售货员的难题(状态压缩动态规划)
- caioj1041:递归11(售货员的难题)
- 【第一次状压DP】售货员问题
- codevs 2596 售货员的难题
- 售货员的难题
- CODEVS 2596 售货员的难题
- [swustoj 411] 售货员的难题
- 售货员的难题(codevs 2596)
- 售货员的难题(luogu1171)
- 洛谷P1171 售货员的难题
- 洛谷P1171 售货员的难题
- P1171 售货员的难题