hdu 1074 Doing Homework(状压DP)

Doing Homework

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>

using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxn = (1<<15)+10;

struct node {
    int deadline;//截止时间
    int how_day;//花费的时间
    char name[110];
} nxt[20];

int dp[maxn];
int time[maxn];
int print[maxn];

void output(int x) { //打印路径 dfs
    if(!x)
        return;

    output( x - (1<<print[x]) );

    printf("%s\n", nxt[print[x]].name);//字典序
}

int main() {
    freopen("data.in", "r", stdin);
    int T, n;
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        for(int i = 0; i < n; i++)
            scanf("%s %d %d", nxt[i].name, &nxt[i].deadline, &nxt[i].how_day);
        int total = 1<<n;

        memset(time, 0, sizeof(time));
        memset(print, 0, sizeof(print));
        memset(dp, 0, sizeof(dp));

        //全排列问题,状压dp
        for(int i = 1; i < total; i++) {
            dp[i] = INF;

            for(int j = n-1; j >= 0; j--) {
                int temp = 1<<j;
                if(!(i & temp))
                    continue;//没有写j门课的作业则跳出循环

                int score = time[i-temp] + nxt[j].how_day - nxt[j].deadline;//扣得分数
                score = max(score,0);//扣得分数不可能是负的
                if(dp[i] > dp[i-temp] + score) { //如果当前状态可以更优则更新dp值,和time的值
                    dp[i] = dp[i-temp] + score;
                    time[i] = time[i-temp] + nxt[j].how_day;
                    print[i] = j;//修改路径
                }
            }
        }
        //所有课作业做完应该所有为都为1,就是1<<n-1
        printf("%d\n", dp[total-1]);//输出扣得分数
        output(total - 1);//打印路径
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/ccshijtgc/article/details/82994133