HDU 1158【簡單dp】
阿新 • • 發佈:2018-05-03
set def mon 工資 ret names clu while ace
題意:給你一個項目,需要幾個月來完成買,同時也給你每個月最少需要的工人數。並且告訴你hiring,firing每個工人的錢數,以及每個月應付每個工人的工資。求項目完成時最小花費。
這是個簡單dp,思路就是枚舉一下上一個月和本月的工人數,寫個狀態轉移方程即可。
#include<stdio.h> #include<string.h> #include<queue> #include<iostream> #define MAX 6000 #define INF 0x3f3f3f3f using namespace std; typedef long long ll; int s, h, f; int num[MAX]; int mon; int dp[MAX][13]; int max(int a, int b) { return (a > b) ? a : b; } int min(int a, int b) { return (a < b) ? a : b; } int main(void) { int maxx = 0; int ans = 0; while (~scanf("%d", &mon) && mon) { memset(dp, INF, sizeof(dp)); ans = INF; scanf("%d%d%d", &h, &s, &f); for (int i = 1; i <= mon; i++) { scanf("%d", &num[i]); maxx = max(maxx, num[i]); } if (mon == 1) { ans = num[mon] * (h + s); printf("%d\n", ans); } else { for (int i = num[1]; i <= maxx; i++) { dp[i][1] = i * (h + s); } for (int i = 2; i <= mon; i++) { for (int j = num[i]; j <= maxx; j++) { for (int k = num[i - 1]; k <= maxx; k++) { if (j == k) dp[j][i] = min(dp[j][i - 1] + j * s, dp[j][i]); else if (j > k) { dp[j][i] = min(dp[k][i - 1] + (j - k)*(h + s) + k * s, dp[j][i]); } else { dp[j][i] = min(dp[k][i - 1] + f * (k - j) + s * j, dp[j][i]); } } } } for (int i = num[mon]; i <= maxx; i++) { ans = min(ans, dp[i][mon]); } printf("%d\n", ans); } } return 0; }
HDU 1158【簡單dp】