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

有n(n<=15)门课需要做作业,每门课所需时间是used_time以及每门课作业上交的最后期限是deadline,晚交一天扣一分,现在来安排最好的写作业计划,让最终的扣除分数最少;
 
由于n的取值范围不大所以我们可以枚举除所有的状态进行判断是否是最优的即可,状态数为2^n-1;
我们可以用状态压缩来表示出各种状态;二进制中的第i为为1代表第i门课已经完成了。
 
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <string>
using namespace std; #define N 1050
#define MOD 1000000007
#define met(a, b) memset(a, b, sizeof(a))
#define INF 0x3f3f3f3f typedef long long LL; int n, pre[N]; struct course
{
char name[];
int deadline, use_time;
} Course[]; struct Status
{
int scores;///当前状态能扣除的最少分数;
int times;///当前状态所需的总时间;
} dp[<<]; void solve(Status& A, Status B, course C)///更新dp;
{
int Times = B.times + C.use_time; int Score = B.scores + max(Times - C.deadline, ); if( A.scores > Score || ( A.scores == Score && A.times > Times ))
{
A.scores = Score;
A.times = Times;
}
} Status dfs(int sta)
{
if( dp[sta].scores != - )///记忆化搜索就是防止一个状态被重复搜索,所以要更新dp的值;
return dp[sta]; dp[sta].scores = INF; for(int i=; i<n; i++)
{
if( sta & (<<i) )///表示当前状态第i门课已经完成了。所以我们要找达到这种状态的其他状态;
solve(dp[sta], dfs(sta-(<<i)), Course[i]);///sta的状态是由sta-(1<<i)加上第i门课得到的;
}
return dp[sta];
} bool Judge(Status A, Status B, course C)
{
int Times = B.times + C.use_time; int Score = B.scores + max(Times - C.deadline, ); return A.scores == Score && A.times == Times;
} void Puts_Path(int sta)
{
if(sta == ) return ; for(int i=n-; i>=; i--)
{
if( sta&(<<i) && Judge(dp[sta], dp[sta-(<<i)], Course[i]) )///判断当前的状态dp[sta]值是不是由dp[sta-(1<<i)]和Course得到;
{
Puts_Path( sta-(<<i) );
printf("%s\n", Course[i].name);///路径是倒着找的的所以应在回溯的过程输出
break;
}
} } int main()
{
int T; scanf("%d", &T); while(T--)
{
met(dp, -); met(Course, ); scanf("%d", &n); for(int i=; i<n; i++)
scanf("%s %d %d", Course[i].name, &Course[i].deadline, &Course[i].use_time); dp[].scores = dp[].times = ; Status ans = dfs( (<<n) - );///从最后一个状态开始找; printf("%d\n", ans.scores); Puts_Path( (<<n) - );///输出路径;
}
return ;
}

记忆化搜索状态压缩

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <string>
using namespace std; #define N 16
#define MOD 1000000007
#define met(a, b) memset(a, b, sizeof(a))
#define INF 0x3f3f3f3f typedef long long LL; int n, Path[<<N], Limit; struct course
{
char name[];
int deadline, use_time;
} Course[]; struct Status
{
int scores;///当前状态能扣除的最少分数;
int times;///当前状态所需的总时间;
} dp[<<]; void Puts_Path(int sta)
{
if(sta == ) return ; Puts_Path( sta - (<<Path[sta]) ); printf("%s\n", Course[Path[sta]].name);
} int main()
{
int T; scanf("%d", &T); while(T--)
{
met(dp, INF); met(Course, ); met(Path, -); scanf("%d", &n); for(int i=; i<n; i++)
scanf("%s %d %d", Course[i].name, &Course[i].deadline, &Course[i].use_time); dp[].scores = dp[].times = ; Limit = (<<n) - ; for(int i=; i<=Limit; i++)
{
for(int j=n-; j>=; j--)
{
if( i&(<<j) )continue; int Time = dp[i].times + Course[j].use_time; int Score = dp[i].scores + max(Time - Course[j].deadline, ); int t = i + (<<j); if(dp[t].scores > Score)
{
dp[t].scores = Score;
dp[t].times = Time; Path[t] = j;///状态t是由状态1<<j + j得到的;
}
}
} printf("%d\n", dp[Limit].scores); Puts_Path( Limit );///输出路径,只能从最终状态进行找;
}
return ;
}

普通搜索状态压缩

Doing Homework---hdu1074(状态压缩&&记忆化搜索)的更多相关文章

  1. loj 1011(状态压缩+记忆化搜索)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25837 思路:状态压缩+记忆化搜索. #include<io ...

  2. HDU 4628 Pieces(状态压缩+记忆化搜索)

    http://acm.hdu.edu.cn/showproblem.php?pid=4628 题意:给个字符窜,每步都可以删除一个字符窜,问最少用多少步可以删除一个字符窜分析:状态压缩+记忆化搜索  ...

  3. ACM学习历程—ZOJ3471 Most Powerful(dp && 状态压缩 && 记忆化搜索 && 位运算)

    Description Recently, researchers on Mars have discovered N powerful atoms. All of them are differen ...

  4. GYM 101933E 状态压缩 + 记忆化搜索

    题意:我方有n个士兵,敌方有m个,每方士兵都有一个血量,现在有k轮无差别炮火打击,每次都会从存活的士兵中随机选一人,这名士兵的HP就-1,问对方被团灭的概率有多大? 思路:因为n和m的范围很小,我们可 ...

  5. light oj 1011 - Marriage Ceremonies (状态压缩+记忆化搜索)

    题目链接 大概题意是有n个男的n个女的(原谅我这么说,我是粗人),给你一个n*n的矩阵,第i行第j列表示第i个女(男)对第j个男(女)的好感度,然后要安排n对相亲,保证都是正常的(无搞基百合之类的), ...

  6. ACM-ICPC 2018 徐州赛区网络预赛 B BE, GE or NE(博弈,记忆化搜索)

    链接https://nanti.jisuanke.com/t/31454 思路 开始没读懂题,也没注意看数据范围(1000*200的状态,记忆化搜索随便搞) 用记忆化搜索处理出来每个状态的胜负情况 因 ...

  7. hihoCoder-1087 Hamiltonian Cycle (记忆化搜索)

    描述 Given a directed graph containing n vertice (numbered from 1 to n) and m edges. Can you tell us h ...

  8. 【bzoj5123】[Lydsy12月赛]线段树的匹配 树形dp+记忆化搜索

    题目描述 求一棵 $[1,n]$ 的线段树的最大匹配数目与方案数. $n\le 10^{18}$ 题解 树形dp+记忆化搜索 设 $f[l][r]$ 表示根节点为 $[l,r]$ 的线段树,匹配选择根 ...

  9. 状压DP+记忆化搜索 UVA 1252 Twenty Questions

    题目传送门 /* 题意:给出一系列的01字符串,问最少要问几个问题(列)能把它们区分出来 状态DP+记忆化搜索:dp[s1][s2]表示问题集合为s1.答案对错集合为s2时,还要问几次才能区分出来 若 ...

随机推荐

  1. 内网DNS投毒技术劫持会话

    工具列表: tcpdump Ferret Hamster node closurether 拓扑环境: 攻击机:Kali 10.10.10.237 被攻击机: win7 10.10.10.232 因为 ...

  2. sublime text 删除插件

    1.ctrl+shift+p 输入remove package 选择要删掉的插件即可 2.去掉产生临死文件的插件:phptools

  3. db2 over()

    说起 DB2 在线分析处理,可以用很好很强大来形容.这项功能特别适用于各种统计查询,这些查询用通常的SQL很难实现,或者根本就无发实现.首先,我们从一个简单的例子开始,来一步一步揭开它神秘的面纱,请看 ...

  4. 基于.Net实现前端对话框和消息框

    关于前端对话框.消息框的优秀插件多不胜数.造轮子是为了更好的使用轮子,并不是说自己造的轮子肯定好.所以,这个博客系统基本上都是自己实现的,包括日志记录.响应式布局等等一些本可以使用插件的.好了,废话不 ...

  5. Navicat for MySQL使用手记(上)--创建数据库和表

    在管理MySQL数据库的图形化工具中,最为熟知的就是phpMyAdmin和Mysql-Front了,今天跟大家分享另外一个管理mysql数据库的另外一个利器---Navicat MySQL. Navi ...

  6. PL/SQL如何调试Oracle存储过程

    from:http://jingyan.baidu.com/article/3a2f7c2e144d2826aed61167.html 调试过程对找到一个存过的bug或错误是非常重要的,Oracle作 ...

  7. Java精选笔记_JDBC

    JDBC 概述 什么是JDBC JDBC全称是Java数据库连接(Java Database Connectivity),应用程序可通过这套API连接到关系数据库,并使用SQL语句来完成对数据库中数据 ...

  8. Leetcode: mimimum depth of tree, path sum, path sum II

    思路: 简单搜索 总结: dfs 框架 1. 需要打印路径. 在 dfs 函数中假如 vector 变量, 不用 & 修饰的话就不需要 undo 2. 不需要打印路径, 可设置全局变量 ans ...

  9. swift开发之 -- 自动轮播图(UIScrollView+UIPageControl+Timer)

    比较简单,原理就不说了,这里只做记录: 代码如下: 1,准备 var pageControl:UIPageControl? var myscrollView:UIScrollView? var myT ...

  10. 第七篇:几个经典的TCP通信函数

    前言 在TCP通信中要使用到几个非常经典的函数,本文将对这几个函数进行一个简短的使用说明. socket()函数 函数作用:创建一个网际字节流套接字 包含头文件:sys/socket.h ( 后面几个 ...