读入之后换不同的预处理方式会被不同的点卡。。。思路是分开处理a=0的挂件和a>=2的挂件,如何花愉悦值购买a>=2的挂件。
#include <bits/stdc++.h>
#define N 2010
#define mp(a,b) make_pair(a,b)
#define endl '\n'
#define int long long
using namespace std ;
typedef pair<int,int> pii ;
int dp[N][N<<1] , s[N] , pri[N] , n ;
const int inf = (1ll<<62) ;
#define fi first
#define se second
#define pb push_back
vector < int > v0 ;
vector < pii > v2 ;
signed main () {
cin.sync_with_stdio(false) ;
cin >> n ;
int ans = 0 , sta = 1 ;
/*
用这个WA第10个点
for ( int i = 1 , a , b ; i <= n ; i++ ) {
cin >> a >> b ;
if ( a == 1 && (b > 0 ) ) ans += b ; // ok
else if ( a == 0 && (b >= 0 ) ) v0.push_back(b) ; // ???
else if ( a >= 2 && (b >= 0 ) ) sta += a-1 , ans += b ;
else if ( a >= 2 && (b < 0 ) ) v2.push_back({a-1,-b}) ;
else if ( (a <= 1) && (b <= 0) ) continue ;
}
*/
/*
用这个WA第1个点
for ( int i = 1 , a , b ; i <= n ; i++ ) {
cin >> a >> b ;
if ( a == 1 && (b > 0 ) ) ans += b ; // ok , ????
else if ( a == 0 ) v0.push_back(b) ; // ??? a == 0 , b <= 0 ? a == 1 , b <= 0 ?
else if ( a >= 2 && b >= 0 ) sta += a-1 , ans += b ;
else if ( a >= 2 && b < 0 ) v2.push_back({a-1,-b}) ;
}
*/
sort (v0.begin(),v0.end()) ;
reverse (v0.begin(),v0.end()) ;
for ( int i = 1 ; i <= v0.size() ; i++ )
s[i] = s[i-1]+v0[i-1] ;
for ( int j = 1 ; j <= n+1 ; j++ ) pri[j] = inf ;
sort (v2.begin(),v2.end()) ;
reverse(v2.begin(),v2.end()) ;
for ( int i = 1 ; i <= v2.size() ; i++ ) {
if ( v0.size() - v2[i-1].fi >= 0 ) pri[v0.size()] = min ( pri[ v0.size() - v2[i-1].fi ] + v2[i-1].se , pri[v0.size()] ) ;
else pri[v0.size()] = min ( pri[0] + v2[i-1].se , pri[v0.size()] ) ;
for ( int jj = v0.size()-v2[i-1].fi ; jj >= 0 ; jj-- ) {
int j = jj+v2[i-1].fi ;
pri[j] = min( pri[j] , pri[jj] + v2[i-1].se ) ;
}
for ( int j = v0.size(); j >= 0 ; j-- )
pri[j] = min( pri[j+1] , pri[j] ) ;
}
int sum = s[sta] ;
if ( sta >= v0.size() ) sum = s[v0.size()] ;
for ( int i = sta ; i <= v0.size() ; i++ ) {
int now = s[i] - pri[i-sta] ;
sum = max(sum,now) ;
}
ans += sum ;
cout << ans << endl ;
return 0 ;
}