poj3311 TSP问题 状压DP
来源:互联网 发布:易观大数据峰会 编辑:程序博客网 时间:2024/05/18 00:02
题意:从0走遍1~n最后再返回到0,一个点可以走多次,求经过的最短距离。
分析:由于一个点可以走多次,所以需要求出任意两点间的最短距离,就要用到floyd算法,同时接下来可以搜索做复杂度是O(n!),而状态压缩的时间效率就高了,关于DP自己有时候状态转移方程知道了,却不知道如何去实现,循环时哪层放在外面,哪层放在里面,所以很容易把DP写成了暴力的搜索,自己要多想想。
状态转移方程:dp[S][i] = min(dp[S^(1<<(i-1))][j] + dis[j][i],dp[S][i])
四不像的搜索:
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <cctype>#include <vector>#include <set>#include <map>#include <queue>using namespace std;#define ll long longconst int maxn = (1<<10) + 5;const int inf = 0x7f7f7f7f;int g[15][15];int n;int mmin;inline int getone(int x){ int res = 0; while (x) { x &= (x-1); res++; } return res;}void floyd(){ for (int k = 0; k <= n; k++) { for (int i = 0; i <= n; i++) { for (int j = 0; j <= n; j++) g[i][j] = min(g[i][j],g[i][k]+g[k][j]); } }}void dfs(int u, int state, int cur)//写搜索本可以不用二进制{ if (getone(state)==0) { if (mmin > cur+g[u][0]) mmin = cur+g[u][0]; return; } for (int i = 1; i <= n; i++) { if (state&(1<<(i-1)) && g[u][i] != -1) { dfs(i, (1<<(i-1))^state, cur+g[u][i]); } }}int main(){ //freopen("input.txt", "r", stdin); while (cin >> n && n) { for (int i = 0; i <= n; i++) for (int j = 0; j <= n; j++)cin >> g[i][j]; floyd(); mmin = inf; for (int i = 1; i <=n; i++) { dfs(i, (1<<(i-1))^((1<<n)-1), g[0][i]); } cout << mmin << endl; }}
DP:
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <cctype>#include <vector>#include <set>#include <map>#include <queue>using namespace std;#define ll long longconst int maxn = (1<<10) + 5;const int inf = 0x7f7f7f7f;int g[15][15];int f[maxn][12];int n;int mmin;void floyd(){ for (int k = 0; k <= n; k++) { for (int i = 0; i <= n; i++) { for (int j = 0; j <= n; j++) g[i][j] = min(g[i][j],g[i][k]+g[k][j]); } }}int main(){ //freopen("input.txt", "r", stdin); while (cin >> n && n) { for (int i = 0; i <= n; i++) for (int j = 0; j <= n; j++)cin >> g[i][j]; floyd(); for (int s = 1; s < (1<<n); s++)//要先枚举状态,跟floyd有点像,此时i,j之间可以进行松弛操作 { for (int i = 1; i <= n; i++) { if (s&(1<<(i-1))) { if (s == (1<<(i-1)))f[s][i] = g[0][i]; else { f[s][i] = inf; for (int j = 1; j <= n; j++) if (s&(1<<(j-1)) && i != j) f[s][i] = min(f[s^(1<<(i-1))][j]+g[j][i], f[s][i]); } } } } int ans = inf; for (int i = 1; i <= n; i++) if (ans > f[(1<<n)-1][i]+g[i][0]) ans = f[(1<<n)-1][i]+g[i][0]; cout << ans << endl; }}
0 0
- poj3311 TSP问题 状压DP
- POJ3311(TSP问题,状态压缩DP)
- poj3311 经典tsp问题
- poj3311 类TSP问题
- POJ3311 Hie with the Pie(DP:TSP问题)
- POJ3311 Hie with the Pie 【TSP】【状压dp】
- POJ3311(TSP)
- poj3311 状压DP
- HDU_3681 TSP问题,状压DP
- TSP问题(状压DP求解)
- 二进制状态压缩dp(旅行商TSP)POJ3311
- hdu 3001 Travelling (TSP问题,状压dp)
- hdu 4568 (状压dp TSP问题)
- TSP(旅行商问题)-状压dp
- DP求解TSP问题
- poj3311(Hie with the Pie)状压dp
- POJ3311 Hie with the Pie 状压DP
- [POJ3311] Hie with the Pie && 状压DP
- Java Servlet Example
- DP POJ1160
- JQuery与Ajax的结合进行文本框内容验证
- iOS 微信第三方登录
- XML(2)——结识DTD
- poj3311 TSP问题 状压DP
- Linux内核module_param的使用
- vc++ DLL开发小结
- Uva-548-Tree(二叉树与stream与dfs)
- 堆排序
- 抽象类、密封类及类成员(C#)
- 移位运算RGB
- Google 开源技术protobuf
- STL源码剖析 [容器](十)[Binary search tree]