题干:

In Zhejiang University Programming Contest, a team is called "couple team" if it consists of only two students loving each other. In the contest, the team will get a lovely balloon with unique color for each problem they solved. Since the girl would prefer pink balloon rather than black balloon, each color is assigned a value to measure its attractiveness. Usually, the boy is good at programming while the girl is charming. The boy wishes to solve problems as many as possible. However, the girl cares more about the lovely balloons. Of course, the boy's primary goal is to make the girl happy rather than win a prize in the contest.

Suppose for each problem, the boy already knows how much time he needs to solve it. Please help him make a plan to solve these problems in strategic order so that he can maximize the total attractiveness value of balloons they get before the contest ends. Under this condition, he wants to solve problems as many as possible. If there are many ways to achieve this goal, he needs to minimize the total penalty time. The penalty time of a problem is equal to the submission time of the correct solution. We assume that the boy is so clever that he always submit the correct solution.

Input

The first line of input is an integer N (N < 50) indicating the number of test cases. For each case, first there is a line containing 2 integers T (T <= 1000) and n (n <= 50) indicating the contest length and the number of problems. The next line contains n integers and the i-th integer ti (ti <= 1000) represents the time needed to solve the ith problem. Finally, there is another line containing n integers and the i-th integer vi (vi <= 1000) represents the attractiveness value of the i-th problem. Time is measured in minutes.

Output

For each case, output a single line containing 3 integers in this order: the total attractiveness value, the number of problems solved, the total penalty time. The 3 integers should be separated by a space.

Sample Input

2
300 10
10 10 10 10 10 10 10 10 10 10
1 2 3 4 5 6 7 8 9 10
300 10
301 301 301 301 301 301 301 301 301 301
1000 1000 1000 1000 1000 1000 1000 1000 1000 1000

Sample Output

55 10 550
0 0 0

题目大意:

给出比赛时间和题目数,并给出每道题目的耗时以及获得的价值,求所能获得的最大价值,以及获得这个最大价值下的最多题目数以及该情况的最小最少罚时(罚时为每道题目提交的时间之和)。

解题报告:

   首先将这个时间序列问题转化成背包问题,然后考虑:假设最终选定了这些题目,那么最终价值和解题数都是一定的,但是为了得到最小罚时,我们需要贪心先做时间最短的题目,所以我们不妨先按照时间顺序排序。这样就不需要记录最终选择了哪些题了。(否则需要记录选择了哪些题目,然后再排序求ans3,十分不划算)

  然后就是01背包,背包的同时维护这三个信息。

刚开始总是想着两次背包,先背出最大价值,然后再背包出最优解题数,同时维护ans3,,。。反正是WA了、、

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e5 + 5;
int n,T;
struct Node {
	ll val,t;
} node[MAX];
struct N {
	ll val,num,t;
	N(){}
	N(ll val,ll num,ll t):val(val),num(num),t(t){}
	bool operator<(const N b)const{
		if(val != b.val) return val < b.val;
		if(num != b.num) return num < b.num;
		return t > b.t;
	}
} dp[MAX];
bool cmp(Node a,Node b) {
	return a.t < b.t;
}
int main()
{
	int t;
	cin>>t;
	while(t--) {
		scanf("%d%d",&T,&n);
		memset(dp,0,sizeof dp);
		for(int i = 1; i<=n; i++) scanf("%lld",&node[i].t);
		for(int i = 1; i<=n; i++) scanf("%lld",&node[i].val);
		sort(node+1,node+n+1,cmp);
		N ans = N(0,0,0);
		for(int i = 1; i<=n; i++) {
			for(int j = T; j>=node[i].t; j--) {
				N pre = dp[j-node[i].t];
				N tmp = N(pre.val + node[i].val,pre.num + 1,pre.t + j);
				if(dp[j] < tmp) dp[j] = tmp;
				if(ans < dp[j]) ans = dp[j];
			}
		}
		printf("%lld %lld %lld\n",ans.val,ans.num,ans.t);
	}
	
	return 0 ;
}