HDU-4526 威威猫系列故事——拼车记 动态规划

分析:该题有2个地方要注意:所有的车要么不坐要么就坐满,这个贪心策略很容易证明是正确的,还有一点就是最后一辆车除外。

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;

const int MaX = 105;
int N, K, D, S;
struct Node {
    int ti;
    int qz;
}seq[MaX];
int dp[MaX][MaX];
// dp[i][j]表示第i台车来的时候,等候人数为j时的最少开销 

void solve() {
    memset(dp, 0xff, sizeof (dp));
    dp[0][N] = 0; // 初始化
    for (int i = 1; i <= K; ++i) {
        const int &ti = seq[i].ti;
        const int &qz = seq[i].qz;
        for (int j = 0; j <= N; ++j) {
            if (dp[i-1][j] != -1) dp[i][j] = dp[i-1][j] + j*(ti-seq[i-1].ti); // 不乘坐 
            if (j == 0) { // 最后一辆车可能不能坐满 
                for (int k = 1; k <= qz; ++k) {
                    if (k <= N && dp[i-1][k] != -1) {
                        if (dp[i][0] == -1) {
                            dp[i][0] = D + dp[i-1][k] + k*(ti-seq[i-1].ti);
                        } else {
                            dp[i][0] = min(dp[i][0], D + dp[i-1][k] + k*(ti-seq[i-1].ti));
                        }
                    }
                }
            } else {
                if ((j+qz) <= N && dp[i-1][j+qz] != -1) {
                    if (dp[i][j] == -1) {
                        dp[i][j] = D + dp[i-1][j+qz] + (j+qz)*(ti-seq[i-1].ti);
                    } else {
                        dp[i][j] = min(dp[i][j], D + dp[i-1][j+qz] + (j+qz)*(ti-seq[i-1].ti));
                    }
                }
            }
        }
    }
    printf("%d
", dp[K][0]);
}

int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        scanf("%d %d %d %d", &N, &K, &D, &S);
        int sum = 0;
        for (int i = 1; i <= K; ++i) {
            scanf("%d %d", &seq[i].ti, &seq[i].qz);
            sum += seq[i].qz;
        }
        if (sum < N) {
            puts("impossible");
            continue;
        }
        solve();
    }
    return 0;
} 
原文地址:https://www.cnblogs.com/Lyush/p/3413174.html