There are n courses in the course selection system of Marjar University. The i-th course is described by two values: happiness Hi and credit Ci. If a student selects m courses x1, x2, …, xm, then his comfort level of the semester can be defined as follows:
(∑mi=1Hxi)2−(∑mi=1Hxi)×(∑mi=1Cxi)−(∑mi=1Cxi)2
Edward, a student in Marjar University, wants to select some courses (also he can select no courses, then his comfort level is 0) to maximize his comfort level. Can you help him?
解题思路
对数据不够敏感,导致在这题上死磕了近一个半小时。
该题 1≤Hi≤10000,1≤Ci≤100 ,于是 C 的取值范围就成为了突破口。 ΣCi≤50000
针对上述公式 (∑mi=1Hxi)2−(∑mi=1Hxi)×(∑mi=1Cxi)−(∑mi=1Cxi)2 ,令 ∑mi=1Hxi 简记作 SH , ∑mi=1Cxi 简记作 SC ,枚举 SC ,则方程 f(SH)=SH2−SH×SC−SC2 呈开口向上抛物线,且由于 SH,SC>0 , f(0)<0 ,故对于每一个枚举数 SC , SH 的值越大,则公式对应的值越大。
此题即可转换为 01 背包问题,dp[i] 表示 SC 为 i 时最大的 SH 。
代码
#include<bits/stdc++.h>
using namespace std;
struct Node {
int h, c;
} p[510];
long long dp[50010];
int main()
{
int T, n;
scanf("%d",&T);
while(T--)
{
memset(dp, 0, sizeof(dp));
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d %d",&p[i].h, &p[i].c);
for(int i=0;i<n;i++)
{
for(int j=50000;j;j--)
{
if(j < p[i].c) break;
dp[j] = max(dp[j], dp[j - p[i].c] + p[i].h);
}
}
long long ans = 0;
for(int i=1;i<=50000;i++)
ans = max(ans, dp[i]*dp[i] - dp[i]*i - (long long)i*i);
cout<<ans<<endl;
}
}