2017 浙大校赛 Course Selection System(01背包)

来源:互联网 发布:网络直播受众人群 编辑:程序博客网 时间:2024/06/09 01:26

Course Selection System


TimeLimit:1 Second     Memory Limit:65536 KB


Thereare n coursesin the course selection system of Marjar University. Thei-th course is describedby two values: happinessHiand creditCi.If a student selectsmcourses x1,x2,...,xm,then his comfort level of the semester can be defined as follows:

Edward,a student in Marjar University, wants to select some courses (also he canselect no courses, then his comfort level is 0) to maximize his comfort level.Can you help him?

Input

Thereare multiple test cases. The first line of input contains an integer T, indicating the numberof test cases. For each test case:

Thefirst line contains a integer n(1 ≤ n ≤ 500)-- the number of cources.

Eachof the next nlines contains two integers HiandCi(1 ≤Hi≤ 10000, 1 ≤Ci≤ 100).

Itis guaranteed that the sum of all ndoes not exceed 5000.

Wekindly remind you that this problem contains large I/O file, so it'srecommended to use a faster I/O method. For example, you can use scanf/printfinstead of cin/cout in C++.

Output

Foreach case, you should output one integer denoting the maximum comfort.

Sample Input

2
3
10 1
5 1
2 10
2
1 10
2 10

Sample Output

191
0

Hint

Forthe first case, Edward should select the first and second courses.

Forthe second case, Edward should select no courses.


浙大校赛的I题,就是因为在这题上与队友卡了足足三个小时,交了43发WA,直接导致了比赛的崩盘。

做的时候方向完全错了,没有想到用背包去解(而且是最简单的01背包。。。)

其实如果想到了,其实题目很简单,而且代码量极少

思路:

设sigma(h[i])=a,sigma(c[i])=b, 则结果=a*a-a*b-b*b=a*(a-b)-b*b;
即在b确定的情况下,a越大越好;
那么就可以通过计算在容量为b的情况下所能取到a的最大值
(其中b<=n*c[i]=50000,时间复杂度为O(b*n))
最后把每个容量扫一遍即可


#include <bits/stdc++.h>using namespace std;#define mst(a,b) memset((a),(b),sizeof(a))#define f(i,a,b) for(int i=(a);i<=(b);++i)const int maxn = 50005;const int mod = 9973;#define ll long long#define rush() int t;scanf("%d",&t);while(t--)ll n,dp[maxn],h,c;int  main(){    int t;    scanf("%d",&t);    while(t--)    {        mst(dp,0);        scanf("%lld",&n);        for(int i=0;i<n;i++)        {            scanf("%lld%lld",&h,&c);            for(int j=maxn-1;j>=c;j--)                dp[j]=max(dp[j],dp[j-c]+h);        }        ll ans=0;        for(ll i=0;i<maxn;i++)    //这里用int会溢出,因此WA好多次……        {            ans=max(ans,dp[i]*dp[i]-dp[i]*i-i*i);        }        printf("%lld\n",ans);    }    return 0;}




0 0