这道题洛谷上的翻译是错的,最后输出格式那里应该是输出一行所选物品的编号,中间用空格隔开

手动模拟01背包
这道题看上去很像是01背包的模板题,但是很明显,v=1e9,正常的01背包是肯定会爆掉62MB的内存的,所以不可能用普通的01背包来做,
但是转念一想,这道题是由10背包魔改过来的,增加的难度是空间的问题。那么如果可以解决掉空间上的不足,用01背包的思路来做即可
先把物品1或2 分成两组,按价值排序。
模拟01背包,先用前缀和处理第二组(质量为2),然后模拟for循环从0开始,每次取第一组的一个,比较是全拿2最大还是拿当前的这个1总质量最大,最后输出即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1e5+7;
const ll mod=2147483647;
ll n,v,ans,sum;
struct node
{
    ll val,id;
    bool operator<(const node & t)const
    {
        return val>t.val;
    }
}t1[N<<1],t2[N<<1];
ll cnt1,cnt2;

ll pre[N],ans1,ans2;
int main()
{
    scanf("%lld %lld",&n,&v);
    for(int i=1;i<=n;++i)
    {
        ll a,b;
        scanf("%lld %lld",&a,&b);
        if(a==1)t1[++cnt1].val=b,t1[cnt1].id=i;
        if(a==2)t2[++cnt2].val=b,t2[cnt2].id=i;
    }
    sort(t1+1,t1+1+cnt1),sort(t2+1,t2+1+cnt2);
    for(int i=1;i<=cnt2;++i)
        pre[i]=pre[i-1]+t2[i].val;
    for(int i=0;i<=min(cnt1,v);++i)
    {
        sum+=t1[i].val;
        if(sum+pre[min(cnt2,(v-i)/2)]>ans)
        {
            ans=sum+pre[min(cnt2,(v-i)/2)];
            ans1=i,ans2=min(cnt2,(v-i)/2);
        }
    }
    printf("%lld\n",ans);
    for(int i=1;i<=ans1;++i)
        printf("%lld%s",t1[i].id," ");
    for(int i=1;i<=ans2;++i)
        printf("%lld%s",t2[i].id,i==ans2?"\n":" ");
}

有任何疑问欢迎评论哦虽然我真的很菜
<stron>
</stron>