Loading

【dp每日一题】HDU 1074 Doing Homework

大意:

给出n(\(n<=15\))个作业的用时和deadline,如果有作业超过deadline,那么每超过1天就要扣1分(超过多个作业也是1分),问扣分最少的方案,按字典序最小输出(题目保证输入按照字典序递增)

思路:

状压dp,枚举能转移过来的每个状态,更新dp数组即可

#include <bits/stdc++.h>

using namespace std;

const int N = 15 + 5;
typedef long long LL;
int T, n, d[N], t[N], dp[1 << N], l[1 << N], pre[1 << N], res[N], cnt,
    step[1 << N];
string name[N];
int main() {
    cin >> T;
    while (T--) {
        cin >> n;
        for (int i = 0; i < n; i++) {
            cin >> name[i] >> d[i] >> t[i];
        }
        memset(dp, 0x3f, sizeof dp);
        memset(l, 0, sizeof l);
        dp[0] = 0;
        for (int i = 0; i < (1 << n); i++) {
            for (int j = 0; j < n; j++) {
                if ((1 << j) & i) {
                    int prestate = i - (1 << j);
                    int temp = max(0, l[prestate] + t[j] - d[j]);
                    if (dp[prestate] + temp <= dp[i]) {
                        dp[i] = dp[prestate] + temp;
                        l[i] = l[prestate] + t[j];
                        pre[i] = prestate;
                        step[i] = j;
                    }
                }
            }
        }
        cnt = 0;
        int state = ( 1 << n ) - 1;
        cout << dp[state] << endl;
        while (state != 0) {
            res[cnt++] = step[state];
            state = pre[state];
        }

        for (int i = cnt - 1; i >= 0; i--) {
            cout << name[res[i]] << endl;
        }
    }
    return 0;
}
posted @ 2020-12-24 20:48  dyhaohaoxuexi  阅读(79)  评论(0编辑  收藏  举报