HDU 3001 Travelling 状态DP

TSP问题,不懂就是每个点最多访问两次,最少访问一次。

所以,我们可以用三进制来当做状态。

这个题练习了一下三进制……0、1、2

 1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <cstdlib>
5 #include <cmath>
6 #include <algorithm>
7 #include <string>
8 #include <queue>
9 #include <stack>
10 #include <vector>
11 #include <map>
12 #include <set>
13 #include <functional>
14 #include <time.h>
15
16 using namespace std;
17
18 const int INF = 1<<30;
19
20 int Matrix[15][15];
21 int base[70000][15]; //base[i][j]表示 数字i从右边第j位起的三进制值
22 int dp[70000][15];
23 int thr[20];
24 int n, m;
25
26 inline bool check(int x) { //判断是否是最终状态
27 for (int i = 0; i < n; i++) if (!base[x][i]) //如果某一位是0则不是
28 return false;
29 return true;
30 }
31
32 inline void update(int st, int u, int v) { //更新状态
33 int &now = dp[st+thr[v]][v];
34 if (now<0) now = dp[st][u]+Matrix[u][v];
35 else now = min(now, dp[st][u]+Matrix[u][v]);
36 }
37
38 void init() {
39 thr[0] = 1;
40 for (int i = 1; i < 20; i++)
41 thr[i] = thr[i-1]*3;
42 for (int i = 0; i < 70000; i++) {
43 int j = i, k = 0;
44 while (j) {
45 base[i][k++] = j%3;
46 j /= 3;
47 }
48 }
49 }
50
51 void input() {
52 memset(Matrix, -1, sizeof(Matrix));
53 for (int i = 0; i < m; i++) {
54 int x, y, c;
55 scanf("%d%d%d", &x, &y, &c);
56 x--; y--;
57 if (-1==Matrix[x][y]) Matrix[x][y] = Matrix[y][x] = c;
58 else Matrix[x][y] = Matrix[y][x] = min(Matrix[x][y], c);
59 }
60 }
61
62 void solve() {
63 memset(dp, -1, sizeof(dp));
64 for (int i = 0; i < n; i++)
65 dp[thr[i]][i] = 0;
66 for (int i = 1; i < thr[n]; i++) {
67 for (int u = 0; u < n; u++) if (dp[i][u]>-1) { //此状态可达
68 for (int v = 0; v < n; v++) if (u!=v && base[i][v]<2 && Matrix[u][v]>-1){ //可以转移到下一个状态
69 update(i, u, v); //更新下一个状态
70 }
71 }
72 }
73
74 int ans = -1;
75 for (int i = 0; i < thr[n]; i++) if (check(i)) {
76 for (int j = 0; j < n; j++) if (-1 < dp[i][j]) {
77 ans = ans>-1 ? min(ans, dp[i][j]) : dp[i][j];
78 }
79 }
80 printf("%d\n", ans);
81 }
82
83 int main() {
84 #ifdef Phantom01
85 freopen("HDU3001.txt", "r", stdin);
86 #endif //Phanaom01
87
88 init();
89 while (scanf("%d%d", &n, &m)!=EOF) {
90 input();
91 solve();
92 }
93
94 return 0;
95 }

HDU3001

时间: 2024-10-06 03:32:49

HDU 3001 Travelling 状态DP的相关文章

HDU 3001 Travelling 状态压缩dp+3进制

题意:一个人要旅行,他要去n个地方,且这n个地方每个地方最多可以走2次: 给m条路径,寻问最短花费 很明显的状态压缩,但是要求每个点最多只能走两次,就没办法标记当前点走过或是没走过,只能用三进制来表示 1代表地点1被走过一次. 2代表地点1被走过两次. 3(即10)代表地点2被走过一次. 4(即11)代表地点1被走过一次,地点2被走过一次. 5(即12)代表地点1被走过两次,地点2被走过一次. 附AC代码 #include<stdio.h> #include<string.h> i

hdu 3001 Travelling(状态压缩 三进制)

Travelling Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6600    Accepted Submission(s): 2144 Problem Description After coding so many days,Mr Acmer wants to have a good rest.So travelling is

HDU 3001 Travelling (三进制状态压缩 DP)

题意:有 n 个city,可以选择任一城市作为起点,每个城市不能访问超过2次, 城市之间有权值,问访问全部n个城市需要的最小权值. 思路:因为每个城市可以访问最多两次,所以用三进制表示访问的状态. 详细见代码注释!!!! #include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map> #include<cmath> #inclu

hdu 3001 Travelling TSP变形 三进制状压dp

// hdu 3001 TSP问题的变形 // 这次到每个点最多两次,所以可以用三进制的类推 // dp[S][u]表示当前在u点访问状态为S时所得到的最小的开销 // 采用刷表法,即用当前的状态推出它所能转移的状态 // dp[S][u] 可以到达的状态为dp[S+state[v]][v](dist[u][v]!=inf) // dp[S+state[v]][v] = max(dp[S+state[v]][v],dp[S][u]+dist[u][v]); // 其中每个点最多访问2次 // 技

HDU 3001 状压DP

有道状压题用了搜索被队友骂还能不能好好训练了,, hdu 3001 经典的状压dp 大概题意..有n个城市 m个道路  成了一个有向图.n<=10: 然后这个人想去旅行.有个超人开始可以把他扔到任意的一个城市..然后他就在城市之间游荡.要满足他要游玩所有的城市..并且.每个城市最多去两次.要求路程最短..如果他不能游完所有的城市,,那么..就输出-1  否则 输出最短距离 如果用搜索...不靠谱  然后用搜索,, 怎么压缩?? 用一个整型数 i 表示他现在的状态..显然一个城市是要用两位..00

HDU 3001 Travelling(状态压缩DP+三进制)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题目大意:有n个城市,m条路,每条路都有一定的花费,可以从任意城市出发,每个城市不能经过两次以上,要求经过所有城市并且花费最少,求出最小花费. 解题思路:三进制的状态压缩DP,跟二进制还是有一点不一样的,因为三进制没有直接的位运算,还要自己先做处理利用num[i][j]记录数字i各位的三进制表示方便计算,其他的就跟二进制状态压缩没有太大区别了.还有注意: ①开始要将n个起点初始化,dp[bit

HDU 3001 Travelling(DP状态压缩)

Problem Description After coding so many days,Mr Acmer wants to have a good rest.So travelling is the best choice!He has decided to visit n cities(he insists on seeing all the cities!And he does not mind which city being his start station because sup

HDU 3001 Travelling 状压DP

链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题意:还是环游地图的问题,只不过这回旅行者对自己有着严格的要求,地图上每个点的经过次数不能超过两次. 思路:依然是状压DP问题,根上一道很像,只不过这次对于每个点来说有三种状态,分别是未经过,经过一次,经过两次.所以要用三进制的数来进行状态压缩,这个关键点想明白了其他的和上一道基本一样了.对于我来说需要注意的是:能够到达某一个点经过了两次的状态的前一个状态是这个点已经经过了一次的状态,而不是从来未

hdu 3001 Travelling (bfs+状态压缩)

Travelling Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3905    Accepted Submission(s): 1234 Problem Description After coding so many days,Mr Acmer wants to have a good rest.So travelling is