题意:01背包,重量为1-3,价值1-1e9
解:按照重量1-3分类,价值贪心从大到小排序,遍历重量记录中间过程最优价值的1-2-3物品使用个数
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 3e5+10;
int num[4];
LL a[4][N], sum[N];
int cmp(LL x,LL y)
{
return x>y;
}
struct node
{
int c1,c2;
LL v;
}dp[N];
int main()
{
int n, m, w;
scanf("%d %d", &n, &m);
for(int i=0;i<n;i++)
{
LL c;
scanf("%d %lld", &w, &c);
a[w][++num[w]]=c;
}
for(int i=1;i<=3;i++) sort(a[i]+1,a[i]+num[i]+1,cmp);
for(int i=1;i<=num[3];i++) sum[i]=sum[i-1]+a[3][i];
dp[0].c1=dp[0].c2=0,dp[0].v=0;
for(int i=1;i<=m;i++)
{
dp[i]=dp[i-1];
if(dp[i].v<dp[i-1].v+a[1][dp[i-1].c1+1])
{
dp[i].v=dp[i-1].v+a[1][dp[i-1].c1+1];
dp[i].c1=dp[i-1].c1+1;
dp[i].c2=dp[i-1].c2;
}
if(i>=2&&dp[i].v<dp[i-2].v+a[2][dp[i-2].c2+1])
{
dp[i].v=dp[i-2].v+a[2][dp[i-2].c2+1];
dp[i].c1=dp[i-2].c1;
dp[i].c2=dp[i-2].c2+1;
}
}
for(int i=0;i<=num[3];i++)
{
if(m>=i*3&&dp[m].v<dp[m-i*3].v+sum[i])
{
dp[m].v=dp[m-i*3].v+sum[i];
}
}
cout<<dp[m].v<<endl;
return 0;
}