For this problem, I just ran the most basic knapsack with the weights as weights and talent for values, then for each weight >= W in the knapsack compared the ratios of dp[weight] * 1000 / weight and took the largest ratio. My code passed all 10 test cases but the intended solution with binary search + dp seems much more complicated.
The sum of the weights does exceed what I put for MXW in test cases 4-10 but apparently none of the answers require the sum of weights being higher than MXW.
Orz hi benq, here’s my understanding of the question.
If you knapsack and use talent as one of the dp states (instead of weight), then you still get AC, but scdivad doesn’t know if this is the intended solution.
I did the same thing and here is why i think it works. If a weight is more then required, and it’s ratio is the best one out of all other weight greater, it is best to just take that weight. Otherwise, we can use the dp to figure out the best answer with weights less then the required.
I also have a solution to the problem without binary search:
#include <bits/stdc++.h>
using ll = long long;
using namespace std;
// O(nlogn + nw) solution:
// sort the cows with decreasing order of the ratio t / w and then do dp
int main()
{
ifstream cin("talent.in");
ofstream cout("talent.out");
int n, w; cin >> n >> w;
auto greater = [&] (const pair<int, int> &p, const pair<int, int> &q)
{
return (ll) p.first * q.second > (ll) q.first * p.second;
};
vector<pair<int, int>> v(n);
for(int i = 0; i < n; ++i)
{
cin >> v[i].second >> v[i].first;
}
sort(v.begin(), v.end(), greater);
pair<int, int> ans = {0, 1};
auto upd = [&] (pair<int, int> p) // updates answer with new candidate p
{
if(greater(p, ans))
{
ans = p;
}
};
vector<int> dp(w, -1); // dp[i] is the largest sum of t for a group with i sum of w
dp[0] = 0;
for(int i = 0; i < n; ++i)
{
for(int j = w - 1; j >= 0; --j) // loop down so that no cow will be included twice
{
if(dp[j] == -1)
continue;
if(j + v[i].second >= w) // we can safely update the answer because of the manner we sorted the cows
// in other words adding more cows to the current group will never increase the ratio
upd(make_pair(dp[j] + v[i].first, j + v[i].second));
else
dp[j + v[i].second] = max(dp[j + v[i].second], dp[j] + v[i].first);
}
}
cout << (ll) ((long double) ans.first * 1000 / ans.second);
return 0;
}