LA 4256 Salesmen 线性dp

来源:互联网 发布:宋佳和谢天笑 知乎 编辑:程序博客网 时间:2024/04/30 19:53
// 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_popcountlltypedef 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;}

0 0
原创粉丝点击