cumtoj 一起來選課
阿新 • • 發佈:2018-12-18
一起來選課
題目地址:http://192.168.173.163/JudgeOnline/problem.php?cid=1019&pid=7
題目
明澤私立大學有n門課程提供給大一的同學來選課,每門課有兩個數值來描述,開心程度Hi,複雜程度Ci。LW小太陽是個有奇怪癖好的人,假設他這學期要選m門課,把這m門課的Hi之和定義為sumH,Ci之和定義為sumC,並自己定義出本學期的課程舒適度為(sumH)2 - sumH * sumC - (sumC)2。
由於明澤私立大學是一所開放前衛的大學,它可以允許LW小太陽選擇若干門課,使得他的課程舒適度最高(一門課都不選的時候,舒適度為0)
輸入
2
3
10 1
5 1
2 10
2
1 10
2 10
輸出
191
0
題解
01揹包
因為n是500 c[i]是100,所以總共的sumC = 5e4 因此可以列舉每個sumC的出現情況,求得最大的sumH,然後更新答案。
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define Max(a,b) (a>b?a:b) const int N = 505; int n, h[N], c[N]; // 記錄最優答案 ll dp[N*100]; // 記錄最優答案下的sumH ll sumh[N*100]; int main() { // freopen("in.txt","r",stdin); int T; scanf("%d", &T); while(T--) { scanf("%d", &n); int mC =0; for(int i = 1;i <= n; i++) { scanf("%d %d", &h[i], &c[i]); mC += c[i]; } for(int i=0;i<=mC;i++) dp[i] = sumh[i] = 0; for(int i=1; i<=n; i++) { for(int j=mC; j>=c[i]; j--) { ll pre = j - c[i]; sumh[j] = max(sumh[j], sumh[pre] + h[i]); } } /* for(int i=1;i<=mC;i++) { printf("%lld%c",sumh[i], i==mC? '\n':' '); } for(int i=1;i<=mC;i++) { printf("%lld%c",dp[i], i==mC? '\n':' '); } */ ll ans = 0; for(int i=0;i<=mC;i++) { // if(!dp[i]) continue; ll mx = 1ll * sumh[i]*sumh[i] - 1ll*sumh[i]*i- i *i; ans = Max(ans, mx); } printf("%lld\n", ans); } return 0; }