zoukankan      html  css  js  c++  java
  • hdu 1074 Doing Homework(状压dp)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1074

    题意:有n门课,每门课有截止时间和完成所需的时间,如果超过规定时间完成,每超过一天就会扣1分,问怎样安排做作业的顺序才能使得所扣的分最小

    由于课目数最多只有15个,所以可以遍历所有状态1~1<<(n - 1)然后再找最优解至于字典序可以不用考虑题目已经帮你处理好了只要按顺序来就能满足

    字典序小的先

    #include <iostream>
    #include <cstring>
    #include <string>
    #include <stack>
    using namespace std;
    const int M = 1 << 16;
    struct TnT {
        string s;
        int cost , deadline , pre , reduce , now;
    }a[20] , dp[M];
    bool vis[M];
    int main() {
        int t;
        cin >> t;
        while(t--) {
            int n;
            memset(vis , false , sizeof(vis));
            dp[0].cost = 0;
            dp[0].pre = -1;
            dp[0].reduce = 0;
            cin >> n;
            for(int i = 0 ; i < n ; i++) {
                cin >> a[i].s >> a[i].deadline >> a[i].cost;
            }
            int End = 1 << n;
            End--;
            vis[0] = true;
            for(int i = 0 ; i < End ; i++) {
                for(int j = 0 ; j < n ; j++) {
                    int temp = 1 << j;
                    if((i & temp) == 0) {
                        int gg = (i | temp);
                        dp[gg].cost = dp[i].cost + a[j].cost;
                        int reduce = dp[gg].cost - a[j].deadline;
                        reduce = max(0 , reduce);
                        reduce += dp[i].reduce;
                        if(vis[gg]) {
                            if(reduce < dp[gg].reduce) {
                                dp[gg].reduce = reduce;
                                dp[gg].now = j;
                                dp[gg].pre = i;
                            }
                        }
                        else {
                            vis[gg] = true;
                            dp[gg].pre = i;
                            dp[gg].now = j;
                            dp[gg].reduce = reduce;
                        }
                    }
                }
            }
            cout << dp[End].reduce << endl;
            int gl = End;
            stack<int>ss;
            while(dp[gl].pre != -1) {
                ss.push(dp[gl].now);
                gl = dp[gl].pre;
            }
            while(!ss.empty()) {
                cout << a[ss.top()].s << endl;
                ss.pop();
            }
        }
        return 0;
    }
    
  • 相关阅读:
    bzoj3272 Zgg吃东西
    bzoj3894 文理分科
    poj1149 PIGS
    poj1637 Sightseeing tour
    [Wc2007]剪刀石头布
    poj2396 Budget
    [NOI2017]游戏
    CF666E Forensic Examination
    bzoj4889 [Tjoi2017]不勤劳的图书管理员
    CF587F Duff is Mad
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/6112451.html
Copyright © 2011-2022 走看看