HDU 1158【简单dp】

题意:给你一个项目,需要几个月来完成买,同时也给你每个月最少需要的工人数。并且告诉你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;

}







猜你喜欢

转载自www.cnblogs.com/tennant/p/8986416.html