题意:有n件物品(n<=10^5),背包容量为m(m<=10^9),每件物品体积为1或2(已知),并已知价值,求最大背包价值;
思路:贪心;将两种物品按价值从大到小排序,枚举两种物品的数量组合,取最大价值;
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<vector> #include<algorithm> using namespace std; int t,n,m,num1,num2; struct node { int num; int id,w; }q[500100]; int cmp(node a,node b) { return a.w>b.w; } node q1[500100],q2[500100]; int sum1[5001000],sum2[5001000]; int main() { int i,j,k,temp,temp1,temp2,maxx; memset(sum1,0,sizeof(sum1)); memset(sum2,0,sizeof(sum2)); scanf("%d%d",&n,&m); num1=num2=0; for(i=1;i<=n;i++){ scanf("%d%d",&q[i].num,&q[i].w); q[i].id=i; if(q[i].num==1){ q1[++num1]=q[i]; } else{ q2[++num2]=q[i]; } } sort(q1+1,q1+num1+1,cmp); sort(q2+1,q2+num2+1,cmp); maxx=0; for(i=1;i<=num1;i++){ sum1[i]=sum1[i-1]+q1[i].w; } for(i=1;i<=num2;i++){ sum2[i]=sum2[i-1]+q2[i].w; } temp1=temp2=0; for(i=0;i<=n;i++){ if(i>m) break; int cnt=(m-i)/2; if(cnt>num2) cnt=num2; if(maxx<sum1[i]+sum2[cnt]){ maxx=sum1[i]+sum2[cnt]; temp1=i; temp2=cnt; } } printf("%d\n",maxx); for(i=1;i<=temp1;i++) { if(i==1) printf("%d",q1[i].id); else printf(" %d",q1[i].id); } for(i=1;i<=temp2;i++){ if(temp1==0&&i==1) printf("%d",q2[i].id); else printf(" %d",q2[i].id); }printf("\n"); }