前言
事实告诉我们 不要乱定义变量
思路
CODE
// Problem: P4138 [JOISC2014] 挂饰
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4138
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
// Problem: P2738 [USACO4.1]���ʻ�·Fence Loops
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2738
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
#define px first
#define py second
#define pb push_back
typedef pair<int,int> pii;
int dxy[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
const int N = 2e3+10,INF = 0x3f3f3f3f;
struct union_find_set{
int n,p[N];
void init(int N)
{
n = N;
for(int i=1;i<=n;i++)
p[i] = i ;
}
int find(int x)
{
if(p[x]!=x)return p[x] =find(p[x]);
return p[x];
}
bool set_union(int u,int v)
{
return (u = find(u)) ==(v == find(v))?false : p[v] = u ;
}
}ufs;
struct node
{
int a,b;
}p[N];int node_idx;
int n,m,t;
int f[N];
//表示当还有i个剩余挂钩的时,最大的装饰度
int a[N],b[N];
int pl_ans,pl_sum;
int tb[N],tb_idx;
bool cmp(int a,int b)
{
return a>b;
}
int s[N];
void solve()
{
cin>>n;
pl_sum = 1;
for(int i=1;i<=n;i++)
{
//挂钩和开心程度
cin>>a[i]>>b[i];
if(a[i] == 0 )
{
if(b[i]<= 0)
continue;
else//没有挂钩 但是开心的值
{
++tb_idx;
tb[tb_idx] = b[i];
}
}else
{
if(b[i]>=0)
{
pl_sum+=(a[i]-1);
pl_ans+=b[i];
}//必拿
else
{
++node_idx;
p[node_idx] = {a[i]-1,b[i]};
}
}
}
pl_sum = min(pl_sum,n);
//总共就n个物品
for(int i = 0 ;i<= 2000 ;i++)
f[i] = -INF;
for(int i= 0 ; i<=pl_sum;i++)
{
f[i] = 0 ;
}
for(int i =1;i<=node_idx;i++)
for(int j = 2000;j>=p[i].a;j--)
f[j] = max(f[j],f[j-p[i].a] + p[i].b);
for(int i=n-1;i>=0;i--)
f[i] = max(f[i],f[i+1]);
sort(tb+1,tb+1+tb_idx,cmp);
for(int i=1;i<=2000;i++)
s[i] = s[i-1]+tb[i];
int ans = 0 ;
for(int i =0 ;i<=2000;i++)
{
ans =max(ans,f[i]+s[i]);
}
cout<<ans+pl_ans<<endl;
}
int main()
{
ios::sync_with_stdio(false);
solve();
return 0;
}