題目大意:給定月數n,給定僱傭一個人的花費hi,每個人一個月的工資sa和開除一個人的花費fi。再給定每個月需要的最少人數num[i]。求每月怎樣安排僱傭和開除人,使得n個月的花費最少
maxn = max(num[i]);
dp[i][j]:第i月僱j個人的花費
初始化:dp[1][i] = i*(hi+fa);
狀態轉移:
(1)如果該月僱傭的人數j>=上月僱傭的人數k:dp[i][j]=min(dp[i][j],dp[i-1][k]+j*sa+(j-k)*hi);
(2)反之:dp[i][j]=min(dp[i][j],dp[i-1][k]+j*sa+(k-j)*fi);
最後ans = min(dp[n][i]);(num[n]<=i<=maxn);
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 999999999;
const int N = 15;
const int M = 1010;
int dp[N][M];//第i個月僱j個人的花費
int num[N];//人數
int hi, sa, fi;
int n;
int main()
{//可以多僱人,使費用降低,僱人上限maxn
while(~scanf("%d", &n) && n)
{
scanf("%d %d %d", &hi, &sa, &fi);
int maxn = -INF;
for(int i = 1; i <= n; ++i)
{
scanf("%d", &num[i]);
maxn = max(maxn, num[i]);
}
memset(dp, 0x3f, sizeof(dp));//求最小值,將dp初始化爲無窮大
for(int i = 1; i <= maxn; ++i)
dp[1][i] = i*(hi+sa);
for(int i = 2; i <= n; ++i)
for(int j = num[i]; j <= maxn; ++j) //該月的狀態
for(int k = num[i-1]; k <= maxn; ++k)//由上月轉移而來
if(j>=k) dp[i][j] = min(dp[i][j], dp[i-1][k]+j*sa+(j-k)*hi);
else dp[i][j] = min(dp[i][j], dp[i-1][k]+j*sa+(k-j)*fi);
int ans = INF;
for(int i = num[n]; i <= maxn; ++i)
ans = min(ans, dp[n][i]);
printf("%d\n", ans);
}
return 0;
}