题意:
题目给定了公式;给定了 n 个 h 和 c
思路:
我们可以知道的是 要选这个的话,这个 h 要大于 c,(虽然大于c不一定是正数)
这样就有个 “贪心策略”了,就是对于一些 c 的和,我们尽量选择使得 h 的和尽量大的一些;
因为我写的时候已经知道是背包了,,
可能思路上会简单点:一看c的和最大才 5e4,背包的维度就是一维,dp[ i ] 表示选择的c的和为 i 时的 h和的最大值;
最后扫一遍 dp 数组并计算找到最大 答案;
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<set>
#include<queue>
#include<stack>
#include<map>
#define PI acos(-1.0)
#define in freopen("in.txt", "r", stdin)
#define out freopen("out.txt", "w", stdout)
#define kuaidian ios::sync_with_stdio(0);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 5e4, maxd = 1e8;
const ll mod = 1e9 + 7;
const ll INF = 0x7f7f7f7f;
int n;
ll dp[maxn+7];
struct node {
ll h, c;
}a[maxn];
int main() {
int T;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
scanf("%lld %lld", &a[i].h, &a[i].c);
}
memset(dp, 0, sizeof dp);
for(int i = 1; i <= n; ++i) {
for(int j = maxn; j >= a[i].c; --j) {
dp[j] = max(dp[j], dp[j-a[i].c]+a[i].h);
}
}
ll ans = 0;
for(int i = 0; i <= maxn; ++i) {
if(dp[i] > i) ans = max(ans, dp[i]*dp[i] - dp[i]*i - i*i);
}
printf("%lld\n", ans);
}
return 0;
}