POJ 3311 【状态压缩DP】
2015-11-06 21:32
351 查看
题意:
给n个点,给出矩阵代表i到j单向边的距离。
要求,不介意访问每个点的次数,要求访问完每个点,使得路程总和最小。
思路:
由于不介意访问每个点的次数,所以可以先进行FLOYD求出任意两个点之间的最短路,然后就是DP。
同样的,1代表有访问过,0代表没访问过。
dp[s][j]代表访问状态为s的情况下最终到达点j的最优值。
枚举状态s中每一个可以到达的点,从所有可能的点中枚举对其进行更新。
关于状态压缩的细节方面,注意从左边数第i位是从0开始数的,所以第i位代表第i+1个点。
然后状态的总数2^(n)-1.
给n个点,给出矩阵代表i到j单向边的距离。
要求,不介意访问每个点的次数,要求访问完每个点,使得路程总和最小。
思路:
由于不介意访问每个点的次数,所以可以先进行FLOYD求出任意两个点之间的最短路,然后就是DP。
同样的,1代表有访问过,0代表没访问过。
dp[s][j]代表访问状态为s的情况下最终到达点j的最优值。
枚举状态s中每一个可以到达的点,从所有可能的点中枚举对其进行更新。
关于状态压缩的细节方面,注意从左边数第i位是从0开始数的,所以第i位代表第i+1个点。
然后状态的总数2^(n)-1.
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; //dp[s][i]代表从s状态到达城市i的最佳策略 const int inf=0x3f3f3f3f; int pho[15][15]; int dp[1<<12][15]; int main() { int n; scanf("%d",&n); while(n) { for(int i=0;i<=n;i++) { for(int j=0;j<=n;j++) { scanf("%d",&pho[i][j]); } } for(int k=0;k<=n;k++) { for(int i=0;i<=n;i++) { for(int j=0;j<=n;j++) { pho[i][j]=min(pho[i][k]+pho[k][j],pho[i][j]); } } } for(int s=0;s<=(1<<n)-1;s++) { for(int i=1;i<=n;i++) { if(s&(1<<(i-1))) { if(s==(1<<(i-1))) { dp[s][i]=pho[0][i]; } else { dp[s][i]=inf; for(int j=1;j<=n;j++) { if((s&(1<<(j-1)))&&i!=j) { dp[s][i]=min(dp[s][i],dp[s^(1<<(i-1))][j]+pho[j][i]); } } } } } } int ans=inf; for(int i=1;i<=n;i++) { ans=min(ans,dp[(1<<n)-1][i]+pho[i][0]); } printf("%d\n",ans); scanf("%d",&n); } }
相关文章推荐
- linux和vxworks的实时性
- 怎么用bsdsocket搭建一个面对多人的服务器
- (转)HTML的代码(从朋友那转的,看着觉得会有用就转了)
- 一个Self Taught Learning的简单例子
- hdu 4658 Integer Partition(公式)
- SDUT 3115 查找一个数中素数的种类数
- HDU 5532 Almost Sorted Array
- WinIo详细使用说明
- hdu 4657 Find Permutation(高效)
- 解决Eclipse导入项目工程出现The project was not built since错误
- Windows phone开发 页面布局之屏幕方向
- 在STL优先队列中查找
- org.hibernate.InvalidMappingException:
- android的实时视频网络传输的知识与概念
- 今天早点睡觉
- 【DP】 BZOJ 3675: [Apio2014]序列分割
- 杭电1408--精度问题
- 矛盾方程的最小二乘解
- ViewPager 打造 图片幻灯切换
- mysql数据库乱码问题