HDU 1074 Doing Homework (状压DP + 路径记录)

原创 2015年07月07日 21:10:16

前面虽然自己已经了几篇状压DP的题解,但是这道题才是我的第一道状压DP题。


题意:有n个任务,每个任务有两个属性(d :最后期限 c :需要用的天数),主人公必须一项一项完成任务,并且每个任务完成的时间每超出最后期限一天,就要被扣一分。问他能被扣的最少的分数。多情况字典序输出方案。


设dp[S] 为完成状态S中的所有任务的被扣最少分数。

那么dp[S] = min(dp[S],dp[S-{v}] + cost);

cost 为 完成S中的所有任务所用的总时间 - 完成v的最后期限。

因为输出按照字典序,所以枚举v的时候逆序。这个稍微一想应该就明白。


我的代码:

#include<cstdio>
#include<iostream>
#include<stack>

using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 16;

struct Nod{
    char name[105];
    int d,c;
}node[maxn];
int dp[1<<maxn],pre[1<<maxn];
int n;

void solve(){
    int Ed = 1 << n;
    fill(dp,dp+Ed,inf);
    fill(pre,pre+Ed,-1);
    int day,cost,S0,tmp,cnt;
    dp[0] = 0;
    for(int S = 1;S < Ed; S++){
        for(int v = n - 1; v >= 0 ; v--){
            if(!(S >> v & 1)) continue;
            S0 = S - (1 << v);
            day = 0;cost = 0;
            for(int i = 0; i < n ; i++){
                if(S0 >> i & 1) day += node[i].c;
            }
            if(node[v].d < day + node[v].c) cost = day + node[v].c - node[v].d;
            if(dp[S] > dp[S0] + cost){
                dp[S] = dp[S0] + cost;
                pre[S] = S0;
                //cout<<S<<" "<<S0<<" "<<v<<" "<<dp[S]<<endl;
            }
        }
    }
    printf("%d\n",dp[Ed-1]);
    tmp = Ed - 1;
    stack<int> stk;
    while(pre[tmp] != -1){
        cnt = 0;
        while(!((tmp ^ pre[tmp]) >> cnt & 1)) cnt++;
        stk.push(cnt);
        tmp = pre[tmp];
    }
    while(!stk.empty()){
        int top = stk.top();stk.pop();
        printf("%s\n",node[top].name);
    }
}

int main(){
    int cas;
    scanf("%d",&cas);
    while(cas--){
        scanf("%d",&n);
        for(int i = 0 ;i < n; i++){
            scanf("%s%d%d",node[i].name,&node[i].d,&node[i].c);
        }
        solve();
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu1074Doing Homework【状态压缩】

Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of h...
  • zhou_yujia
  • zhou_yujia
  • 2016年01月07日 09:45
  • 567

HDU1074:Doing Homework(状态压缩DP)

Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of ...
  • libin56842
  • libin56842
  • 2014年04月22日 17:01
  • 6268

HDU1074 Doing Homework

Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot o...
  • starcuan
  • starcuan
  • 2014年02月06日 17:42
  • 957

HDU - 1074 Doing Homework

题意:学生有多个任务,每个任务有规定完成的时间,还有完成的时间,超过规定一天就扣一分,求最少的扣分,相同的话,按字典序 思路:DP的状态搜索,每次枚举一个,然后从第一个开始匹配,因为题目已经排序...
  • u011345136
  • u011345136
  • 2014年07月02日 15:54
  • 763

hdu-1074-Doing Homework

状态压缩dp.. #include #include #include #include #include using namespace std; #define inf 0x3f3f3f3f ...
  • u010489389
  • u010489389
  • 2014年02月15日 01:10
  • 492

HDU_1789_DoingHomeworkAgain

Doing Homework again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot...
  • baidu_29410909
  • baidu_29410909
  • 2015年07月29日 23:25
  • 337

HDU 1074 Doing Homework (状压dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1074 题意:有n项作业,给出每项作业需要的时间和截止日期,每超出1天扣一分,问如何选择使得扣...
  • csdn364988181
  • csdn364988181
  • 2016年01月17日 15:34
  • 147

HDU 1074 Doing Homework 状压Dp

题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=68966#problem/D 题意:给定各个科目的截至时间和完成该科目所需要的...
  • I_am_a_winer
  • I_am_a_winer
  • 2015年05月02日 00:18
  • 330

hdu 1074 Doing Homework (状压dp)

Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others...
  • u010228612
  • u010228612
  • 2013年09月10日 23:28
  • 1012

HDU 1074 Doing Homework(状压DP)

题目地址:HDU 1074 这题攒了好长时间了。。。一直没写。。 简单状压DP。这题比较特别的地方是dp需要用结构体数组。 详细的请看kuangbin大神的模板。。传送门 代码如下: #in...
  • u013013910
  • u013013910
  • 2014年10月16日 15:45
  • 830
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU 1074 Doing Homework (状压DP + 路径记录)
举报原因:
原因补充:

(最多只允许输入30个字)