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. float和clear

    简介 float CSS属性指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它.该元素从网页的正常流动中移除,尽管仍然保持部分的流动性. 浮动元素是float值不为none的元素. 可能 ...

  2. Linux I/O 映射(ioremap)和writel/readl

    在裸奔代码中,如果要控制gpio,直接控制gpio寄存器地址即可: 在linux系统中,所有操作的地址都是虚拟地址,都是由linux内核去管理,所以需要将物理地址转换成内核可识别的虚拟地址. 1.io ...

  3. 关于ListView和GridView的应用

    这两篇博文分别讲的很好: ListView: http://www.cnblogs.com/noTice520/archive/2011/12/05/2276379.html GridViw: htt ...

  4. python一个简单的web服务器和客户端

    服务器:      当客户联系时创建一个连接套接字      从这个连接接收HTTP请求(*)      解释该请求所请求的特定文件      从服务器的文件系统获取该文件      并发送文件内容 ...

  5. 上一步是硬件描述语言,下一步是FPGA

    上一步是硬件描述语言,下一步是FPGA. 学习了硬件描述语言(Verilog或者VHDL)之后,FPGA该如何继续. 世上没有捷径,每一步都得踏踏实实的走.学习FPGA也是这样,在有了硬件描述语言的基 ...

  6. js大法处理无法点击的问题

    js定位的其他方法:

  7. Oracle redo与undo

    Undo and redo Oracle最重要的两部分数据,undo 与redo,redo(重做信息)是oracle在线(或归档)重做日志文件中记录的信息,可以利用redo重放事务信息,undo(撤销 ...

  8. activemq artemis安装运行及其在springboot中的使用

    安装 创建broker 在springboot中的使用 依赖 配置 Producer Consumer Rest使用 安装 http://activemq.apache.org/artemis/dow ...

  9. 使用PreparedStatement接口实现增删改操作

    直接上下代码: package com.learn.jdbc.chap04.sec02; import java.sql.Connection; import java.sql.PreparedSta ...

  10. 使用Selenium对付一个点击游戏

    继续来熟悉Selenium的使用,这次来玩一个Html5游戏.原网址在这:http://tianmaying.com/app/clicking/# 游戏是这样的,5秒内你能点击这个按钮几次.一般人都只 ...