寒假复健第一天 cf1475D

题目:有n个手机软件,每个有ai的空间与bi的便利度,问怎样删软件,可以至少删掉m的空间并且损失的便利度最小。

本来想找DP题练练的,结果这怎么看可以直接贪。

因为便利度只有2种,那么同样便利度里面只要选最大的空间就可以了。

所以分别按照便利度1 2存,然后大到小排序,尽可能的选取2然后再尝试用1替换2,一遍遍历下来一定能找到最优解。

下附代码:

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int INF=0X3f3f3f3f;
 5 ll n,m,v[200005],a[200005],b[200005];
 6 bool cmp(ll x, ll y){
 7     return x>y;
 8 }
 9 int main(){
10     int T;
11     scanf("%d",&T);
12     while (T--){
13         scanf("%d%d",&n,&m);
14         int l1=0,l2=0;
15         for (int i=1; i<=n; i++){
16             scanf("%d",&v[i]);
17         }
18         for (int i=1; i<=n; i++){
19             int x;
20             scanf("%d",&x);
21             if (x==1){
22                 a[++l1]=v[i];
23             }
24             else {
25                 b[++l2]=v[i];
26             }
27         }
28         sort(a+1,a+1+l1,cmp);
29         sort(b+1,b+1+l2,cmp);
30         ll sum=0,res=INF,j=1;
31         for (j=1; j<=l2; j++){
32             sum+=b[j];
33             if (sum>=m || j==l2) break;
34         }
35         if (l2==0) j=0;
36         if (sum>=m) res=j*2;
37         for (int i=1; i<=l1; i++){
38             sum+=a[i];
39             while (j>=1 && sum-b[j]>=m){
40                 sum-=b[j];
41                 j--;
42             }
43             if (sum>=m) res=min(res,i+j*2);
44         }
45         if (sum<m) printf("-1\n");
46         else printf("%lld\n",res);
47     }
48 }
View Code

 

posted @ 2021-01-27 22:35  我是菜狗QAQ  阅读(83)  评论(0编辑  收藏  举报