competitive-programming2021년 1월 30일1분 분량
[Codeforces] 1475D. Cleaning the Phone 풀이
수정일: 2021년 12월 31일
Two pointersSortingsMeet in the middle
지원 언어:enko
#Problem
#Approach
이 문제는 "Two pointers" 문제입니다.
먼저 편의 점수를 기준으로 를 두 개의 배열로 나누고, 각각을 내림차순으로 정렬합니다.
이 배열들을 각각 one과 two라고 부르겠습니다.

one에서 l개의 앱을, two에서 r개의 앱을 선택한다고 합시다.
시작은 다음과 같습니다.
l= 0r= two.size()
이미 삭제하기로 결정한 앱(r개)을 제외할 때는, 크기가 작은 앱부터 탐욕적으로 선택합니다.
반대로 새로운 앱을 추가할 때는 크기가 큰 앱부터 선택합니다.
처음에는 메모리의 합이 각각 sum1 = 0, sum2 = 6입니다.

이제 l = 0, 1, ... one.size()에 대해 다음을 반복합니다:
- 이 만족될 때까지 를 수행하고
r을 감소시킵니다. - answer = min(answer,
l+ 2*r)



정렬에 이, 순회에 이 걸립니다.
#Code

/**
* written: 2022-03-17 20:26:37 Thu [KST]
* @jooncco's mac.
**/
#include <bits/stdc++.h>
using namespace std;
#define FAST_IO ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define f first
#define s second
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef deque<int> di;
typedef deque<ll> dl;
typedef priority_queue<int, vi, less<int> > maxHeap;
typedef priority_queue<int, vi, greater<int> > minHeap;
const ll INF= 1e16;
int n,m;
void solve() {
cin >> n >> m;
vi arr(n);
for (int &mem : arr) cin >> mem;
vi one, two;
int conv;
for (int i=0; i < n; ++i) {
cin >> conv;
if (conv == 1) one.push_back(arr[i]);
if (conv == 2) two.push_back(arr[i]);
}
sort(one.rbegin(), one.rend());
sort(two.rbegin(), two.rend());
ll ans= INF;
ll sum1= 0, sum2= accumulate(two.begin(), two.end(), 0ll);
int r= two.size();
for (int l=0; l <= one.size(); ++l) {
while (r > 0 && sum1 + sum2 - two[r-1] >= m) {
sum2 -= two[--r];
}
if (r > -1 && sum1 + sum2 >= m) ans= min(ans, l+2ll*r);
if (l < one.size()) sum1 += one[l];
}
cout << (ans == INF ? -1 : ans) << "\n";
}
int main() {
FAST_IO;
int t; cin >> t;
while (t--) solve();
}
#Complexity
- Time:
- Space: