[클래식 DP] Employment Planning
A project manager wants to determine the number of the workers needed in every month. He does know the minimal number of the workers needed in each month. When he hires or fires a worker, there will be some extra cost. Once a worker is hired, he will get the salary even if he is not working. The manager knows the costs of hiring a worker, firing a worker, and the salary of a worker. Then the manager will confront such a problem: how many workers he will hire or fire each month in order to keep the lowest total cost of the project.
Input
The input may contain several data sets. Each data set contains three lines. First line contains the months of the project planed to use which is no more than 12. The second line contains the cost of hiring a worker, the amount of the salary, the cost of firing a worker. The third line contains several numbers, which represent the minimal number of the workers needed each month. The input is terminated by line containing a single '0'.
Output
The output contains one line. The minimal total cost of the project.
Sample Input
3
4 5 6
10 9 11
0
Sample Output
199
대략적인 제목의 뜻:
제1행위 N은 분기를 대표한다(분기마다 하나의 상태).
두 번째 줄에는 세 가지 숫자가 있는데 그것이 바로hir(채용비),sal(월급),fir(해고비)이다.
세 번째 줄에는 N개의 숫자가 있는데 매 분기에 몇 명이 필요한지 나타낸다.
상태 방정식을 찾는 방법:
본 문제에 대해 상태는 현재(이 분기)와 이전 상태(지난 분기)를 대상으로 한다.또한 지난 시즌의 인원수에 따라 이번 분기의 채용 여부와 해고 여부에 영향을 미친다.
따라서num[13]: 12개월(최대)을 대표하고 매 분기 몇 명이 필요합니까?
dp[i][j]: i분기 수요를 대표하여 j개인을 보류한다.
상태 방정식: (1) 현재 상태의 수요자가 전 분기보다 많으면 사람을 고용해야 한다. 그래서 자금 비용은 전 분기의 최저 소비 + 이번 분기의 신규 고용비 + 이번 분기의 수요자의 임금
(2) 반대로 지난 분기의 사람이 이번 분기보다 많으면 인원을 줄여야 한다.비용: 지난 분기의 최저 소비 + 이번 분기의 인원수 * 송환비 + 이번 분기의 인원수 * 임금
(1)dp[i-1][k]+(j-k)*hiring+j*salary에 대해;
(2) dp[i-1][k]+(k-j)*firing+j*salary;
둘 사이에서 최소치를 찾아내면 dp[i][j]이고 마지막으로 최소치를 찾으면 된다.
AC 코드:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int dp[20][500];//* i j ;
int hiring , salary , firing; //* , , ;
int num[13];//*
int main()
{
int month ;
while(cin>>month, month)
{
memset(dp,0,sizeof(dp));
memset(num , 0 ,sizeof(num));
int maxi = - 1 ;
cin>>hiring>>salary>>firing;
for(int i = 1 ; i <=month ;i++)
{
cin>>num[i];//* ;
if(maxi<num[i])
{
maxi = num[i]; //* ;
}
}
for(int i= num[1] ; i<=maxi;i++) //* ;
{
dp[1][i] = i*hiring + i*salary; //*
}
int mini , cost ;
for(int i= 2 ; i<= month ; i++)
{
for(int j = num[i] ; j<=maxi ; j++)
{
mini = 9999999 ;
for(int k = num[i-1] ; k <=maxi ; k++)
{
if(k<=j)
cost = dp[i-1][k]+(j-k)*hiring+j*salary;
else cost = dp[i-1][k]+(k-j)*firing+j*salary;
if(mini >cost )
mini = cost ;
}
dp[i][j] = mini ;
}
}
mini = 99999999 ;
for(int i = num[month]; i<=maxi;i++)
{
if(dp[month][i] < mini )
{
mini = dp[month][i] ;
}
}
cout << mini <<endl;
}
return 0 ;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.