*[topcoder]AstronomicalRecords
http://community.topcoder.com/stat?c=problem_statement&pm=12804&rd=15706
首先A和B的长度都不一定一样,里面的元素也不一定有序。比如,A={1,4,6,7,2,8} and B={1,3,5,6,8,2,9,10}。二来,因为A和B都是代表着ratio,那么选定A[i]和B[j],假设他们是同一个,就可以把A和B数组normalize。方法是A*B[j],B*A[i]。此时问题就转化成最长公共子序列了。另外要注意,因为用了乘法,所以元素可能超过int,要用long表示。
#include <set> #include <vector> using namespace std; class AstronomicalRecords { public: int minimalPlanets(vector <int> A, vector <int> B); private: int sub(vector<long> A, vector<long> B, int i, int j); }; int AstronomicalRecords::sub(vector<long> A, vector<long> B, int x, int y) { int p = A[x]; int q = B[y]; for (int i = 0; i < A.size(); i++) { A[i] *= q; } for (int i = 0; i < B.size(); i++) { B[i] *= p; } vector<vector<int> > dp(A.size()+1); for (int i = 0; i < dp.size(); i++) dp[i].resize(B.size()+1, 0); // i, j for the length int m = 0; for (int i = 0; i <= A.size(); i++) { for (int j = 0; j <= B.size(); j++) { if (i == 0 || j == 0) dp[i][j] = 0; else if (A[i-1] == B[j-1]) dp[i][j] = dp[i-1][j-1] + 1; else dp[i][j] = dp[i-1][j-1]; m = max(dp[i][j], m); } } return m; } int AstronomicalRecords::minimalPlanets(vector <int> _A, vector <int> _B) { vector<long> A; vector<long> B; for (int i = 0; i < _A.size(); i++) { A.push_back(_A[i]); } for (int i = 0; i < _B.size(); i++) { B.push_back(_B[i]); } int max_seq = 0; for (int i = 0; i < A.size(); i++) { for (int j = 0; j < B.size(); j++) { max_seq = max(sub(A, B, i, j), max_seq); } } return A.size() + B.size() - max_seq; }