HDU1074 Doing Homework

  

  题意:给了n个家庭作业,然后给了每个家庭作业的完成期限和花费的实践,如果完成时间超过了期限,那么就要扣除分数,然后让你找出一个最优方案使扣除的分数最少,当存在多种方案时,输出字典序最小的那种,因为题意已经说了家庭作业的名字是按照字典序从小到大输入的,所以处理起来就好多了。

分析:此题的关键是如何记录路径,具体看代码

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath> using namespace std;
#define MAX 1<<15+1
int N;
struct Node{
char name[];
int deadline;
int cost;
}homework[];
struct START
{
int time;
int pre;
int score;
int now;
} dp[MAX];
int record[]; void DP()
{
int Final=(<<N)-,punish,previous;
dp[].id=dp[].now=dp[].pre=dp[].score=dp[].time=;
for(int i=;i<=Final;i++)
{
dp[i].score=;
for(int j=;j<N;j++)
if(i&(<<j))
{
previous=(i-(<<j));
if(dp[previous].time+homework[j].cost>homework[j].deadline)
punish=dp[previous].time+homework[j].cost-homework[j].deadline;
else punish=;
if(dp[i].score>=dp[previous].score+punish)
{
dp[i].score=dp[previous].score+punish;
dp[i].time =dp[previous].time+homework[j].cost;
dp[i].pre=previous;
dp[i].now=j;
}
}
}
printf("%d\n",dp[Final].score);
int cal=Final,num=;
while(cal)
{
record[num++]=dp[cal].now;
cal=dp[cal].pre;
}
for(int i=num-;i>=;i--)
puts(homework[record[i]].name); }
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&N);
for(int i=;i<N;i++)scanf("%s%d%d",homework[i].name,&homework[i].deadline,&homework[i].cost);
DP();
}
return ;
}

  做这题做的很是沮丧,在DP()中把j写成j+1了,看了很久愣是没看出来,慢慢调试了将近1小时后才发现。

 void DP()
{
int Final=(<<N)-,punish,previous;
dp[].id=dp[].now=dp[].pre=dp[].score=dp[].time=;
for(int i=;i<=Final;i++)//状态从全0到全1
{
dp[i].score=;//为了找出最小值所以先初始化成比较大的值
for(int j=;j<N;j++)//题编号
if(i&(<<j))//状态i中有题j,为什么这样写是因为保证在状态全一的时候
//枚举过每一种可能,即由状态previous转化成状态j
{
previous=(i-(<<j));//从previous到i仅相差一个作业
//若从状态previous再做一题总时间加起来超过了作业j的deadline,记录扣几分
//否则为零
if(dp[previous].time+homework[j].cost>homework[j].deadline)
punish=dp[previous].time+homework[j].cost-homework[j].deadline;
else punish=;
//寻找状态为i时候的最小值
if(dp[i].score>=dp[previous].score+punish)
{
dp[i].score=dp[previous].score+punish;
dp[i].time =dp[previous].time+homework[j].cost;
dp[i].pre=previous;
dp[i].now=j;
}
}
}
printf("%d\n",dp[Final].score);
//显示路径now代表的是状态i是由写了一道编号为now的题形成的,previous是i的前一状态
int cal=Final,num=;
while(cal)
{
record[num++]=dp[cal].now;
cal=dp[cal].pre;
}
for(int i=num-;i>=;i--)
puts(homework[record[i]].name); }

状态压缩-----HDU1074 Doing Homework的更多相关文章

  1. 状态压缩 HDU1074

    t组数据 n门课程 底限 完成要几天 dp[i] 表示i的二进制数中  1 对应位置课程 完成  最少扣多少分 完成的时间 记录一下怎么下来的 1->2^n 列举 (1<<n)   ...

  2. hdu1074 Doing Homework(状态压缩DP Y=Y)

    Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T ...

  3. HDU1074 Doing Homework 状态压缩dp

    题目大意: 根据完成任务的截止时间,超时一天罚1分,求完成所有任务后的最小罚时 这里n最大为15,可以利用状态压缩来解决问题 /* 首先要明白的一点是状态1/0分别表示这件事做了还是没做 而1/0的位 ...

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

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

  5. HDU1074(KB12-D 状态压缩dp)

    Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  6. HDU1074(状态压缩DP)

    Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

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

    题目大意: 有 n 项作业需要完成,每项作业有上交的期限和需完成的天数,若某项作业晚交一天则扣一分.输入每项作业时包括三部分,作业名称,上交期限,完成所需要的天数.求出完成所有作业时所扣掉的分数最少, ...

  8. HDU 1074 Doing Homework(状态压缩)

    之前做过一个题,是在学贪心的时候做的,所以这个题就想当然的跑偏了,当看到N是<=16 的时候,状态压缩就理所当然了 #include<iostream> #include<cs ...

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

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

随机推荐

  1. Oracle中的存储过程简单例子

    --创建表create table TESTTABLE(  id1  VARCHAR2(12),  name VARCHAR2(32))select t.id1,t.name from TESTTAB ...

  2. window下安装mysql

    参考地址: https://www.cnblogs.com/lmh2072005/p/5656392.html http://www.jb51.net/article/90302.htm 一.下载安装 ...

  3. mysql各种集群的优缺点

    mysql各种集群的优缺点 1.主从架构:只是有数据备份的功能: 2.主主互备+keepalived:实现数据备份加高可用: 3.主主互备,主主下面分别挂个从: 4.A和B主主互备,把从库都挂到B下, ...

  4. emqtt 3 (我要subscribe 这个topic)

    这一次,主要分析client subscribe 某个topic 的处理流程. 由protocol开始 是的,还是要从protocol开始,至于为什么,之前就说过了. subscribe 类型的pac ...

  5. PHP 判断手机号归属地 和 运营商的免费接口

    在项目开发的时候,需要去查询又一批手机号或者固话的具体信息(归属地 运营商) 就需要写一个脚本,来批量请求接口来得到我们想要的数据 学习源头:https://blog.csdn.net/shaerdo ...

  6. FPGA学习中的代码阅读

    不管是学FPGA还是C语言,任何一种代码的学习都离不开大量的代码阅读,也就是多看,多学习别人的代码.初学者在学习的过程中更为重要的是模仿,模仿别人的代码算法怎么去处理的,模仿多了,代码看的多了,能力自 ...

  7. 显示等待 之 text_to_be_present_in_element 判断元素是否有xx 文本信息 用法

  8. python学习(十五) 屏幕抓取

    15.1 屏幕抓取 15.1.1 Tidy和XHTML解析 Tidy:用来修复不规范且随意的HTML文档的工具. 为什么用XHTML: 和旧版本的HTML之间最主要的区别:HTML可能只用一个开始标签 ...

  9. linux 混杂设备驱动之adc驱动

    linux2.6.30.4中,系统已经自带有了ADC通用驱动文件---arch/arm/plat-s3c24xx/adc.c,它是以平台驱动设备模型的架构来编写的,里面是一些比较通用稳定的代码,但是l ...

  10. 为何指针初始化为NULL

    指针初始化为NULL,指向NULL指针区(大小64K),如果读取或写入这个地址,会引发内存写保护异常 版权声明:本文为博主原创文章,未经博主允许不得转载.