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(感受一下就行了)
时间: 2024-11-13 21:56:14