码迷,mamicode.com
首页 > 其他好文 > 详细

递推DP UVA 1424 Salesmen

时间:2015-08-05 12:18:31      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:

 

题目传送门

 1 /*
 2    题意:给定包含n个点的无向图和一个长度为L的序列,修改尽量少的点使得相邻的数字相同或连通
 3    DP:状态转移方程:dp[i][j] = min (dp[i][j], dp[i-1][k] + (j != a[i]));
 4         dp[i][j]表示前i个数字以j结尾的最小花费。我自己写了很长时间,很复杂,状态转移的不好。
 5         应该能知道前一个状态的所有情况,每一维数组记录的就是一个状态
 6 */
 7 /************************************************
 8 Author        :Running_Time
 9 Created Time  :2015-8-5 9:03:34
10 File Name     :UVA_1424.cpp
11  ************************************************/
12 
13 #include <cstdio>
14 #include <algorithm>
15 #include <iostream>
16 #include <sstream>
17 #include <cstring>
18 #include <cmath>
19 #include <string>
20 #include <vector>
21 #include <queue>
22 #include <deque>
23 #include <stack>
24 #include <list>
25 #include <map>
26 #include <set>
27 #include <bitset>
28 #include <cstdlib>
29 #include <ctime>
30 using namespace std;
31 
32 #define lson l, mid, rt << 1
33 #define rson mid + 1, r, rt << 1 | 1
34 typedef long long ll;
35 const int MAXN = 1e2 + 10;
36 const int INF = 0x3f3f3f3f;
37 const int MOD = 1e9 + 7;
38 bool con[MAXN][MAXN];
39 int a[MAXN*2];
40 int dp[MAXN*2][MAXN];
41 int n1, m, n;
42 
43 int work(void)  {
44     memset (dp, INF, sizeof (dp));
45     for (int i=1; i<=n1; ++i)   {
46         dp[1][i] = (i != a[1]);
47     }
48     for (int i=2; i<=n; ++i)    {
49         for (int j=1; j<=n1; ++j)   {
50             for (int k=1; k<=n1; ++k)   {
51                 if (con[j][k])  {
52                     dp[i][j] = min (dp[i][j], dp[i-1][k] + (j != a[i]));
53                 }               
54             }
55         }
56     }
57     int res = INF;
58     for (int i=1; i<=n1; ++i)    {
59         res = min (res, dp[n][i]);
60     }
61 
62     return res;
63 }
64 
65 int main(void)    {     //UVA 1424 Salesmen
66     int T;  scanf ("%d", &T);
67     while (T--) {
68         scanf ("%d%d", &n1, &m);
69         memset (con, false, sizeof (con));
70         for (int i=1; i<=n1; ++i)   con[i][i] = true;
71         for (int i=1; i<=m; ++i)    {
72             int u, v;   scanf ("%d%d", &u, &v);
73             con[u][v] = con[v][u] = true;
74         }
75         scanf ("%d", &n);
76         for (int i=1; i<=n; ++i)    {
77             scanf ("%d", &a[i]);
78         }
79 
80         printf ("%d\n", work ());
81     }
82 
83     return 0;
84 }
技术分享
  1 /************************************************
  2 Author        :Running_Time
  3 Created Time  :2015-8-5 9:03:34
  4 File Name     :UVA_1424.cpp
  5  ************************************************/
  6 
  7 #include <cstdio>
  8 #include <algorithm>
  9 #include <iostream>
 10 #include <sstream>
 11 #include <cstring>
 12 #include <cmath>
 13 #include <string>
 14 #include <vector>
 15 #include <queue>
 16 #include <deque>
 17 #include <stack>
 18 #include <list>
 19 #include <map>
 20 #include <set>
 21 #include <bitset>
 22 #include <cstdlib>
 23 #include <ctime>
 24 using namespace std;
 25 
 26 #define lson l, mid, rt << 1
 27 #define rson mid + 1, r, rt << 1 | 1
 28 typedef long long ll;
 29 const int MAXN = 1e2 + 10;
 30 const int INF = 0x3f3f3f3f;
 31 const int MOD = 1e9 + 7;
 32 bool con[MAXN][MAXN];
 33 vector<int> G[MAXN];
 34 vector<int> pre;
 35 int a[MAXN*2];
 36 int dp[MAXN][2][MAXN];
 37 int n1, m, n;
 38 
 39 int work(void)  {
 40     memset (dp, INF, sizeof (dp));    pre.clear ();
 41     dp[1][0][a[1]] = 0;
 42     for (int i=1; i<=n1; ++i)   {
 43         if (i == a[1])  continue;
 44         pre.push_back (i);
 45         dp[1][1][i] = 1;
 46     }
 47     for (int i=2; i<=n; ++i)    {
 48         if (con[a[i-1]][a[i]])  {
 49             dp[i][0][a[i]] = dp[i-1][0][a[i-1]];
 50             pre.clear ();   continue;
 51         }
 52         vector<int> tmp;
 53         for (int j=0; j<pre.size (); ++j)   {
 54             int u = pre[j];
 55             for (int k=0; k<G[u].size (); ++k) {
 56                 int v = G[u][k];
 57                 if (con[u][v])  {
 58                     if (v == a[i])  dp[i][0][v] = min (dp[i][0][v], dp[i-1][1][u]);
 59                     else    dp[i][1][v] = min (dp[i][1][v], dp[i-1][1][u] + 1);
 60                     tmp.push_back (v);
 61                 }
 62             }
 63         }
 64         pre.clear ();
 65         for (int j=0; j<tmp.size (); ++j)   pre.push_back (tmp[j]);
 66     }
 67 
 68     int res = INF;
 69     res = min (res, dp[n][0][a[n]]);
 70     for (int i=0; i<pre.size (); ++i)   {
 71         int v = pre[i];
 72         res = min (res, dp[n][1][v]);
 73     }
 74 
 75     //debug
 76     for (int i=1; i<=n; ++i)    {
 77         printf ("%d ", dp[i][0][a[i]]);
 78     }
 79     puts ("");
 80 
 81     return res;
 82 }
 83 
 84 int main(void)    {
 85     int T;  scanf ("%d", &T);
 86     while (T--) {
 87         scanf ("%d%d", &n1, &m);
 88         memset (con, false, sizeof (con));
 89         for (int i=1; i<=n1; ++i)   G[i].clear ();
 90         for (int i=1; i<=n1; ++i)   con[i][i] = true;
 91         for (int i=1; i<=m; ++i)    {
 92             int u, v;   scanf ("%d%d", &u, &v);
 93             con[u][v] = con[v][u] = true;   G[u].push_back (v); G[v].push_back (u);
 94         }
 95         scanf ("%d", &n);
 96         for (int i=1; i<=n; ++i)    {
 97             scanf ("%d", &a[i]);
 98         }
 99 
100         printf ("%d\n", work ());
101     }
102 
103     return 0;
104 }
undone(感受一下就行了)

 

递推DP UVA 1424 Salesmen

标签:

原文地址:http://www.cnblogs.com/Running-Time/p/4704128.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!