TopCoder SRM 588 DIV 2 500 maxSongs
Failed to pass system tests during the competition through simple greedy strategy. I thought it can be solved by DP, but had no clear way to go.
After the competition, I finally found out that the result must be a subset of the vector sorted by tone!
So, we can degrade the original arrangement problem (O(n!)) to a combination problem (O(2^n)), and then calculate through simple brute force since the number of elements is less than 16. ~_~
It has a DP solution here, I would study it later.
My degraded brute force solution source in C++:
#include <vector> #include <list> #include <map> #include <set> #include <queue> #include <deque> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> using namespace std; struct song { int dur; int tone; bool operator<(const song& a) const { return tone < a.tone; } }; class GUMIAndSongsDiv2 { public: int calc(vector<song> &s, int val, int T) { int ret = 0, sum = 0; int lastTone = -1; int i = 0; for (vector<song>::iterator it = s.begin(); it != s.end(); it ++) { if ((val & (1LL << i)) != 0) { sum += (*it).dur; if (lastTone >= 0) { sum += (*it).tone - lastTone; } lastTone = (*it).tone; ret ++; } i ++; } return sum <= T ? ret : 0; } int maxSongs(vector <int> duration, vector <int> tone, int T) { vector<song> s; for (int i = 0; i < duration.size(); i ++) { song so; so.dur = duration[i]; so.tone = tone[i]; s.push_back(so); } sort(s.begin(), s.end()); int kinds = pow(2, duration.size()); int maxCount = 0; for (int i = 0; i < kinds; i ++) { int cur = calc(s, i, T); if (cur > maxCount) { maxCount = cur; } } return maxCount; } }; <%:testing-code%> //Powered by KawigiEdit 2.1.4 (beta) modified by pivanof!