[CF3B]Lorry

题目大意:
  有$n(n\leq 10^5)$个物品,背包的容量为$m(m\leq 10^9)$。每个物品有重量$w_i(w_i\in\{1,2\})$和价值$v_i(v_i\leq 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\n",ans);
41     for(register int i=1;i<=n;i++) {
42         if(b[i]) printf("%d ",i);
43     }
44     return 0;
45 }

 

posted @ 2018-01-10 10:57  skylee03  阅读(169)  评论(0编辑  收藏  举报