// LA 4256 Salesmen 线性dp // // 像LCS和LIS问题类似,因为每次修改一个值,都是根据 // 前一个值决定的,那么最后一个结尾的数字肯定要作为 // 状态,而长度作为状态是一目了然的 // // d[i][j]表示长度为i,最后以j结尾的数组修改的最小次数 // // 则状态转移方程为 // // d[i][j] = min(d[i][j],d[i-1][k]+(j,k是否相同或者相邻?0:1)); // // 个人感觉还是比较明显的,最后的答案就是min(d[L][k]); // // 初始化的时候注意一下,对d[i][1,2,...n]都是i.(最坏每次都修改一次) // 这样就可以轻松ac了。 // // 这题以前在自己很水的时候硬啃不知道了多久过了, // 现在再捡起来,就感觉简单多了,但还是有点不太顺畅, // 还是没有自己想出来的有趣啊,题目一定要尽量自己做, // 这是我目前最受益的一句话 // 继续练 #include <algorithm> #include <bitset> #include <cassert> #include <cctype> #include <cfloat> #include <climits> #include <cmath> #include <complex> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <deque> #include <functional> #include <iostream> #include <list> #include <map> #include <numeric> #include <queue> #include <set> #include <stack> #include <vector> #define ceil(a,b) (((a)+(b)-1)/(b)) #define endl '\n' #define gcd __gcd #define highBit(x) (1ULL<<(63-__builtin_clzll(x))) #define popCount __builtin_popcountll typedef long long ll; using namespace std; const int MOD = 1000000007; const long double PI = acos(-1.L); template<class T> inline T lcm(const T& a, const T& b) { return a/gcd(a, b)*b; } template<class T> inline T lowBit(const T& x) { return x&-x; } template<class T> inline T maximize(T& a, const T& b) { return a=a<b?b:a; } template<class T> inline T minimize(T& a, const T& b) { return a=a<b?a:b; } const int maxn = 300; int mp[maxn][maxn]; int a[maxn]; int n,L; int dp[maxn][maxn]; void show(){ for (int i=1;i<=L;i++){ for (int j=1;j<=n;j++){ cout << dp[i][j] << " "; } cout << endl; } } void init(){ int x,y; int m; scanf("%d%d",&n,&m); memset(mp,0,sizeof(mp)); for (int i=1;i<=n;i++){ mp[i][i]=1; } for (int i=1;i<=m;i++){ scanf("%d%d",&x,&y); mp[x][y] = 1; mp[y][x] = 1; } scanf("%d",&L); for (int i=1;i<=L;i++) scanf("%d",&a[i]); for (int i=1;i<=L;i++) for (int j=1;j<=n;j++) dp[i][j]= i; for (int j=1;j<=n;j++) dp[0][j] = 0; } void solve(){ for (int i=1;i<=L;i++) for (int j=1;j<=n;j++){ for (int k=1;k<=n;k++){ if (mp[j][k]){ dp[i][j] = min(dp[i][j],dp[i-1][k]+(j==a[i]?0:1)); } } } int mi = L; for (int i=1;i<=n;i++) mi = min(mi,dp[L][i]); printf("%d\n",mi); } int main() { int t; //freopen("G:\\Code\\1.txt","r",stdin); scanf("%d",&t); while(t--){ init(); solve(); //show(); } return 0; }
原文地址:http://blog.csdn.net/timelimite/article/details/46352549