Knapsack (Greedy) :  Greedy Results
Difficulty: Hard

Take a look at the following video to understand greedy knapsack algorithm.

* The Knapsack problem is a pretty famous combinatorial problem which states the following
	* Given a set of items, each with a mass and a value, find the number of each item to include in a collection so that the total weight is less than or equal to a given limit and the total value is as large as possible.
    
* The problem is optimally solved using Dynamic Programming when a 0-1 approach is used (where an item is either fully taken or fully rejected)

* However, a greedy approximation exists, where the items are chosen according to ratio of value to mass.

* For a 0-1 approach, the greedy solution fails to produce an optimal answer as compared to a DP approach, however , the Fractional Knapsack problem, has an optimal greedy solution.
    

[(iframe youtube ZFK9_jgCBrE 560 315)] 

__Online Resources:__ 

[Link 1](http://oucsace.cs.ohiou.edu/~razvan/courses/cs4040/lecture15.pdf)

[Link 2](http://www.cs.upc.edu/~mjserna/docencia/algofib/P06/tr111.pdf)


__Algorithm:__

	* Item i has benefit bi and weighs wi.
	* So its value (per pound) is vi=bi/wi.
	* Make the greedy choice and pick the most valuable item and take all of it or as much as the knapsack can hold.
	* Pick the second most valuable and do the same.
	* This clearly is optimal since it never makes sense to leave over some valuable item to take some less valuable item.
    ** The algorithm stops when the knapsack acannot hold anymore items.
    
The implementation oriented algorithm is as :

	GreedyKnapsack(S,W)
    {
   		Input:  Set S of items i with weight wi and benefit bi all positive.
           Knapsack capacity W>0.
   		Output: Amount xi of i that maximizes the total benefit without
           exceeding the capacity.

   		for each i in S do
      		xi ← 0        { for items not chosen in next phase }
      		vi ← bi/wi    { the value of item i "per pound" }
   			w ← W            { remaining capacity in knapsack }

   		while w > 0 do
      		remove from S an item of maximal value   { greedy choice }
      		xi ← min(wi,w)  { can't carry more than w more }
      		w ← w-xi
      }


__Problem:__

Given a set of __N__ items, each with a weight Wi and a value Vi, find the number of each item to include in a collection so that the total weight is less than or equal to a given limit __X__ and the total value is as large as possible.

It is required to find the results of two greedy strategies (defined above), as follows :

* Where the choice on items is 0-1 (Integer), either taken or rejected.

* Where the choice on items can be fractional (an item can be partially chosen)

Print the results of the given knapsack problem, using the above two strategies, in the same order as above.



Input Format:
First line consists of a single integer __T__, denoting the number of test cases.
First line of each test case, contains a single integer __N__, denoting the number of items.

The next two lines containing __N__ space separated integes each, where the first line  deontes the weights of N items, and the second line denotes the value associated with each of the __N__ items.

The last line of each test case, denotes the capacity __X__ of the knapsack.

__Constraints:__

1<= T <=10

1<= N <=1000

1<= X <=1000

The weights and values will easily fit in a 32-bit integer.

Output Format:
For each test case, print a single lines containing two integer, first, an integer deonting the result of first strategy and second, an integer (integeral part of the floating point value), denoting answer to the second strategy.

Sample Input:
1

5

12 1 2 1 4

4 2 2 1 10

15

Sample Output:
15 17

Python 3 starter code:


Reference solution (C++):
	#include <iostream>
	#include<cstdio>
	#include<cstdlib>
	#include<algorithm>
	using namespace std;
	struct obj
	{
		int wt,v;
	};
	bool cmp(struct obj a,struct obj b)
	{
		double ratio1 = a.v*1.0 / a.wt;
    	double ratio2 = b.v*1.0 / b.wt;
    	if(ratio1 > ratio2) 
    		return 1;
    	else 
    		return 0;
	}
	int main() 
	{
	//freopen("inp1.txt","r",stdin);
	//freopen("op1.txt","w",stdout);
	int t,n,X,i;
	cin>>t;
	while(t--)
	{
		cin>>n;
		obj xx[n];
		for(i=0;i<n;i++)
		cin>>xx[i].wt;
		for(i=0;i<n;i++)
		cin>>xx[i].v;
		cin>>X;
		sort(xx,xx+n,cmp);
		
		int Y=X;
		int ans1=0;
		for(i=0;i<n;i++)
		{
			if(Y>=xx[i].wt)
			{
				ans1+=xx[i].v;
				Y-=xx[i].wt;
			}
			else
			break;
		}
		//cout<<Y<<endl;
		double ans2 = 0.0;
        int pw = 0;
        for(i=0;i<n;i++)
        {
                if(pw + xx[i].wt< X)
                {
                        pw += xx[i].wt;
                        ans2+=xx[i].v;
                }
                else
                {
                        int rem=X-pw;
                        ans2+= xx[i].v*rem*1.0/xx[i].wt; 
                        break;
                }
        }       
		cout<<ans1<<" "<<(int)ans2<<endl;
	}
	return 0;
}