• HDU 1074 Doing Homework DP 状压DP


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

      题目描述: 给你所有课程的截止时间和工作时长, 一次只能做一种作业, 问最少罚时几天 N <= 15

      解题思路: 由于N很小, 所以第一反应就是状压DP, 我们可以用一个15位二进制数来表示各个课程做完还是没做完, 然后从 S 从 1 到 1 << N 枚举 i 从 1 到 N 枚举, 如果S & (1<<i) 有效则说明i 属于情况 S, 这样我们从上一步S - 1 << i 转移过来就可以, 记录路径就是每当出现答案的更新就将此时的状态和当前处理的位数记住, 压入栈中, 最后再倒着打出来

      代码: 

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <map>
    #include <cstring>
    #include <iterator>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <deque>
    #include <set>
    #include <iterator>
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    using namespace std;
    
    const int maxn = 20;
    int deadline[maxn];
    int cost[maxn];
    string name[maxn];
    const int INF = 0x3fffffff;
    set<string> ans;
    struct node {
        int time, score, pre, now;
    };
    node dp[1<<15];
    set<string>::iterator it;
    
    int main() {
        int t;
        cin >> t;
        while( t-- ) {
            ans.clear();
            memset(dp, 0, sizeof(dp));
            int n;
            cin >> n;
            for( int i = 0; i < n; i++ ) {
                cin >> name[i] >> deadline[i] >> cost[i];
            }
            int end = 1 << (n);
    //        cout << end << endl;
            for( int s = 1; s < end; s++ ) {
                dp[s].score = INF;
                for( int i = n-1; i >= 0; i-- ) {
                    int temp = 1 << i;
                    if( temp & s ) {
                        int past = s- temp;
                        int st = dp[past].time + cost[i] - deadline[i];
                        if( st < 0 ) st = 0;
                        if( st + dp[past].score <  dp[s].score ) {
                            dp[s].score = st + dp[past].score;
                            dp[s].pre = past;
                            dp[s].now = i;
                            dp[s].time = dp[past].time + cost[i];
                        }
                    }
                }
            }
    
            stack<int> S;
            int tem = end-1;
            cout << dp[tem].score << endl;
            while(tem)
            {
                S.push(dp[tem].now);
                tem = dp[tem].pre;
            }
            while(!S.empty())
            {
                cout << name[S.top()] << endl;
                S.pop();
            }
        }
        return 0;
    }
    View Code

      思考: 自己一开始只知道是状压DP, 具体该怎么做还是不知道, 要接触各种DP

  • 相关阅读:
    MDK+VS+Eclipse的STM32库V3.5工程模板的建立(六)
    MDK+VS+Eclipse的STM32库V3.5工程模板的建立(一)
    MDK+VS+Eclipse的STM32库V3.5工程模板的建立(四)
    ognl.OgnlException: target is null for setProperty(null, "username", [Ljava.lang.String;@19af9e98)
    Hibernate联合主键Annotation
    struts2入门第一天配置环境
    为什么java的构造方法中this()或者super()要放在第一行
    几种解决IE6下PNG图片透明问题
    IE6解决min_height
    一个拖拽例子
  • 原文地址:https://www.cnblogs.com/FriskyPuppy/p/7340616.html
Copyright © 2020-2023  润新知