题目大意:
有$n(nleq 10^5)$个物品,背包的容量为$m(mleq 10^9)$。每个物品有重量$w_i(w_iin{1,2})$和价值$v_i(v_ileq 10^4)$。问最多能装下总价值为多少的物品,并输出任意一种方案。
思路:
贪心。
首先对两种物品分别排序,从大到小贪心,尽可能把重量为$1$的物品选上去,不够的用重量为$2$的补。然后用重量为$2$的替换掉一部分重量为$1$的,看一下时候会把答案变大。
1 #include<cstdio> 2 #include<cctype> 3 #include<vector> 4 #include<algorithm> 5 inline int getint() { 6 register char ch; 7 while(!isdigit(ch=getchar())); 8 register int x=ch^'0'; 9 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 10 return x; 11 } 12 const int N=100001; 13 bool b[N]; 14 std::vector<std::pair<int,int> > v[2]; 15 int main() { 16 const int n=getint(); 17 int m=getint(),tmp=0,ans=0,j=0; 18 for(register int i=1;i<=n;i++) { 19 const int x=getint(); 20 tmp+=x; 21 v[x-1].push_back(std::make_pair(getint(),i)); 22 } 23 m=std::min(m,tmp); 24 std::sort(v[0].rbegin(),v[0].rend()); 25 std::sort(v[1].rbegin(),v[1].rend()); 26 v[0].resize(std::min((int)v[0].size(),m)); 27 for(register int i=0;i<(int)v[0].size();i++) { 28 ans+=v[0][i].first; 29 b[v[0][i].second]=true; 30 } 31 for(register int i=v[0].size();i<m;i++) { 32 v[0].push_back(std::make_pair(0,0)); 33 } 34 std::sort(v[0].begin(),v[0].end()); 35 for(register int i=0;i+1<(int)v[0].size()&&v[1][j].first>v[0][i].first+v[0][i+1].first;i+=2,j++) { 36 ans+=v[1][j].first-v[0][i].first-v[0][i+1].first; 37 b[v[0][i].second]=b[v[0][i+1].second]=false; 38 b[v[1][j].second]=true; 39 } 40 printf("%d ",ans); 41 for(register int i=1;i<=n;i++) { 42 if(b[i]) printf("%d ",i); 43 } 44 return 0; 45 }