之前做过一道二进制压缩的题目,感觉也不是很难吧,但是由于见少识窄,这道题一看就知道是撞鸭dp,却总是无从下手....最后看了一眼博客,才顿悟,本次做这道题的作用知识让自己更多的认识二进制压缩,并无其它卵用......呜呜呜~~~

  本题大意:到期末了,某同学的n位老师给他布置了n门家庭作业,要求他在布置作业后的D天之内完成,并且已知它每门作业所需的天数C,每门作业超时一天就要扣一分,让你求出要如何合理安排做作业的顺序才能使他扣掉的总分最少......还需要输出做作业的顺序和最优情况下扣的分数......

  本题思路:因为要得到所有做题的顺序就有n!种这么多,那么此时我们看到n  <= 15,那就能考虑到二进制撞鸭了,二进制撞鸭之前发过一个博客有讲过,这里再强调一下比如0101表示第1和3科的作业做了,第二科作业没做,那么我们可以枚举做作业先后的所有的情况,然后取最优即可,这只是思路,那么具体我们要如何分析这个问题呢

下面我详细讲解......

  首先思考一个问题:我们二进制枚举所有的写作先后过程,那么我们的dp要保存什么状态呢,第一我们需要先找出最小分数即score,需要回溯保存一个过程的上一个过程pre,需要每次写作业之后更新已经过去的时间time,需要保存当前正在写作业的下标ind,就ok了,对于dp[ i ],我们在所有科目中逆序寻找(为什么是逆序寻找呢....因为我们需要利用一个数组存做作业的先后顺序,也就是利用一个pre存它之前完成的状态的编号,遍历输出时顺序也是反的,为了保证字典序输出,我们只能逆着遍历,~~~~(>_<)~~~~呜呜呜~~~),如果发现i状态下如果已经完成了作业j,那么我们就将作业j分离出来在这一步单独再次完成,在这一步利用dp[i - 1<<j]将dp[ i ]的值更新并找到最小值(由于在完成三项任务1, 2, 3时肯定要完成对应的前两项1,2 || 2,3 || 1,3),那么我们的最优值就是由这个思路得来的,由于i - 1<<j 恒小于i,所以它在i之前求得,我们就可以对dp[ i ]的值进行更新,那么对于dp[ i ],我们就可以写出他的状态转移方程dp[ i ] = max(dp(i - 1 << j) + dp[ j ])(j 为状态i 的一个子问题)。

  参考代码:

 #include <iostream>
#include <cstring>
#include <string>
#include <stack>
using namespace std; const int maxn = + , INF = 0x3f3f3f3f;
int t, n;
struct node {
string name;
int deadline, cost;
} a[maxn];
struct node1 {
int pre, time, score, ind;
} dp[ << ]; int main () {
ios::sync_with_stdio(false);
cin >> t;
while(t --) {
cin >> n;
for(int i = ; i < n; i ++)
cin >> a[i].name >> a[i].deadline >> a[i].cost;
memset(dp, , sizeof dp);
int nbit = << n;
for(int i = ; i < nbit; i ++) {
dp[i].score = INF;
for(int j = n - ; j >= ; j --) {
int temp = << j;
if(!(temp & i)) continue;
int tem = i - temp;
int t = dp[tem].time + a[j].cost - a[j].deadline;
t = t > ? t : ;
if(t + dp[tem].score < dp[i].score) {
dp[i].score = t + dp[tem].score;
dp[i].pre = tem;
dp[i].ind = j;
dp[i].time = dp[tem].time + a[j].cost;
}
}
}
cout << dp[nbit - ].score << endl;
stack<int> q;
int t = nbit - ;
while(dp[t].time) {
q.push(dp[t].ind);
t = dp[t].pre;
}
while(!q.empty()) {
int k = q.top();
cout << a[k].name << endl;
q.pop();
}
}
return ;
}

HDU-1074.DoingHomework(撞鸭dp二进制压缩版)的更多相关文章

  1. HDU 1074 Doing Homework (dp+状态压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目大意:学生要完成各科作业, 给出各科老师给出交作业的期限和学生完成该科所需时间, 如果逾期一 ...

  2. HDU 1074 Doing Homework(DP状态压缩)

    题意:有n门功课需要完成,每一门功课都有时间期限以及你完成所需要的时间,如果完成的时间超出时间期限多少单位,就会被减多少学分,问以怎样的功课完成顺序,会使减掉的学分最少,有多个解时,输出功课名字典序最 ...

  3. HDU 4336 Card Collector (期望DP+状态压缩 或者 状态压缩+容斥)

    题意:有N(1<=N<=20)张卡片,每包中含有这些卡片的概率,每包至多一张卡片,可能没有卡片.求需要买多少包才能拿到所以的N张卡片,求次数的期望. 析:期望DP,是很容易看出来的,然后由 ...

  4. hdu 4336 Card Collector(期望 dp 状态压缩)

    Problem Description In your childhood, people in the famous novel Water Margin, you will win an amaz ...

  5. BestCoder Round #52 (div.2) HDU 5418 Victor and World (DP+状态压缩)

    [题目链接]:pid=5418">click here~~ [题目大意]: 问题描写叙述 经过多年的努力,Victor最终考到了飞行驾照. 为了庆祝这件事,他决定给自己买一架飞机然后环 ...

  6. hdu 4352 数位dp + 状态压缩

    XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  7. 【状态DP】 HDU 1074 Doing Homework

    原题直通车:HDU  1074  Doing Homework 题意:有n门功课需要完成,每一门功课都有时间期限t.完成需要的时间d,如果完成的时间走出时间限制,就会被减 (d-t)个学分.问:按怎样 ...

  8. hdu 4057 AC自己主动机+状态压缩dp

    http://acm.hdu.edu.cn/showproblem.php?pid=4057 Problem Description Dr. X is a biologist, who likes r ...

  9. HDU 1074 Doing Homework (动态规划,位运算)

    HDU 1074 Doing Homework (动态规划,位运算) Description Ignatius has just come back school from the 30th ACM/ ...

随机推荐

  1. 白鹭引擎 - 显示对象与 HelloWord ( 绘制了一个红蓝相间的 2 x 2 格子 )

    1: 白鹭引擎默认实在一个 640 * 1136 的画布上作画 2: 入口文件 Main.ts,  类 Main 是程序的入口 // 1, 在一个宽高为 640 * 1136 的画布上作画 // 2, ...

  2. div的全屏与退出全屏

    div的全屏与退出全屏 作用:将div全屏与退出全屏,一般播放器使用较多. html按钮: <button onclick="showFull();"> 全屏 < ...

  3. Appium -选择、操作元素3

    UI Automator API定位 id .class name.acessibility id.xpath底层都是通过UI Automator API定位,UI Automator测试框架提供了一 ...

  4. react-native android打包

    看了官网测试的是可以的,自己整理下,方便后面查看 先是生产安卓证书,安卓证书生成,点这里.这里掠过 生成安卓证书,记住2个密码 秘钥库口令 和 私钥密码 1.然后把你生成的安卓证书放到文件放到你工程中 ...

  5. Cmake 编译opengl开源库glfw工程及使用

    使用的是cmake gui进行编译的,路径输入好之后,点configure配置vs版本,这里是vs2013版本,然后如果画面出现红色的 需要再点击一下 Generate 然后直接点open proje ...

  6. English-旅游英语及情景对话

    1.旅游英语:预订机票情景对话及常用句型 目前,越来越多的人都选择以飞机为出行方式.但是如何用一口流利的英语订机票呢?这里我们替你总结了一些情景对话,还有一些常用的句型.大家都来学一学吧~A:Good ...

  7. pod引用第三方库的几种方式

    pod引用库的原理,本质上是去找.podspec文件,podspec中包含库的地址及最新的版本号(tag标签),如果pod时没有指定版本,则pod install时会去下载podspec文件中指定的最 ...

  8. 如何遍历List对象

    for(String str : list) {//其内部实质上还是调用了迭代器遍历方式,这种循环方式还有其他限制,不建议使用. System.out.println(str); } .普通for循环 ...

  9. java实现excel表格导出

    Java 实现导出excel表 POI 1.首先下载poi-3.6-20091214.jar,下载地址如下: http://download.csdn.net/detail/evangel_z/389 ...

  10. python函数基础:调用内置函数&定义函数

    调用内置函数 有很多内置函数,在使用中需要积累.这里只举两个例子: 分别调用abs和数据类型转换,注意当入参类型错误时候会报错 ''' print('abs(-100)') abs(-100) pri ...