Koder / 박성훈
article thumbnail

https://www.acmicpc.net/problem/18186

 

18186번: 라면 사기 (Large)

라면매니아 교준이네 집 주변에는 N개의 라면 공장이 있다. 각 공장은 1번부터 N번까지 차례대로 번호가 부여되어 있다. 교준이는 i번 공장에서 정확하게 Ai개의 라면을 구매하고자 한다(1 ≤ i ��

www.acmicpc.net

이 문제는 바로 앞 문제이기도 한

 

백준 BOJ 18185 - 라면사기 (Small)

https://www.acmicpc.net/problem/18185 18185번: 라면 사기 (Small) 라면매니아 교준이네 집 주변에는 N개의 라면 공장이 있다. 각 공장은 1번부터 N번까지 차례대로 번호가 부여되어 있다. 교준이는 i번 공장에

koder0205.tistory.com

이 문제와 크게 다른점이 없다

접근도 동일하고

반례도 동일한데

여기서 신경써야 할점은 딱 하나

저기에서 적어놓은 소스처럼

포문돌리면서 하나씩 빼면 시간초과라서

한번에 빼고 cost에도 한번에 더해줘야 한다.

 

그리고 b <= c인 경우에는 (ex. b를 1로, c를 5로 생각해보자)

세개를 연달아서 사는 경우인 b + 2c가 그냥 한개씩 세번 사는 3b보다 커지게 되므로

여기서 문제가 발생해서 틀리게 된다.

해결법은 그냥 b<c일때 c = b로 설정해주면 깔끔하게 AC가 나온다.

c가 b가 되면, 어차피 b + 2c나 3b나 값이 똑같아지게 되므로,

우리가 원하는 대로 (기존의 그리디로) 처리해도 답이 변하지 않게 된다.

이정도만 작성해주면 깔끔하게 AC.

 

#include <stdio.h>

typedef long long int ll;

ll ramen[1000010] = {0};
ll cost=0;
ll n,b,c;
ll t;

ll min(ll a, ll b){return a>b?b:a;}

void three(ll k){
	ll t = min(ramen[k],min(ramen[k+1], ramen[k+2]));
	ramen[k]-=t;
	ramen[k+1]-=t;
	ramen[k+2]-=t;
	cost+=(b+2*c)*t;
}

void two(ll k){
	ll t = min(ramen[k],ramen[k+1]);
	ramen[k]-=t;
	ramen[k+1]-=t;
	cost+=(b+c)*t;
}

void one(ll k){ cost+=b*ramen[k]; }


int main(){
	scanf("%lld %lld %lld", &n, &b, &c);
	if(b<c) c=b;
	for(int i=0; i<n; i++) scanf("%lld", &ramen[i]);
	for(int i=0; i<n; i++){
		if(ramen[i+1] > ramen[i+2]){
			t = min(ramen[i],ramen[i+1]-ramen[i+2]);
			ramen[i]-=t;
			ramen[i+1]-=t;
			cost+=(b+c)*t;
			
			t = min(ramen[i],min(ramen[i+1], ramen[i+2]));
			ramen[i]-=t;
			ramen[i+1]-=t;
			ramen[i+2]-=t;
			cost+=(b+c+c)*t;
		}
		else{
			t = min(ramen[i],min(ramen[i+1], ramen[i+2]));
			ramen[i]-=t;
			ramen[i+1]-=t;
			ramen[i+2]-=t;
			cost+=(b+c+c)*t;
			
		 	t = min(ramen[i],ramen[i+1]);
			ramen[i]-=t;
			ramen[i+1]-=t;
			cost+=(b+c)*t;
		}
		cost+=b*ramen[i];
		ramen[i] = 0;
	}
	printf("%lld", cost);
	return 0;
}

 

반응형