Doing Homework HDU - 1074 (状压dp)
InputThe input contains several test cases. The first line of the input is a single integer T which is the number of test cases. T test cases follow.
Each test case start with a positive integer N(1<=N<=15) which indicate the number of homework. Then N lines follow. Each line contains a string S(the subject's name, each string will at most has 100 characters) and two integers D(the deadline of the subject), C(how many days will it take Ignatius to finish this subject's homework).
Note: All the subject names are given in the alphabet increasing order. So you may process the problem much easier.
OutputFor each test case, you should output the smallest total reduced score, then give out the order of the subjects, one subject in a line. If there are more than one orders, you should output the alphabet smallest one.
Sample Input
2
3
Computer 3 3
English 20 1
Math 3 2
3
Computer 3 3
English 6 3
Math 6 3
Sample Output
2
Computer
Math
English
3
Computer
English
Math
Hint
In the second test case, both Computer->English->Math and Computer->Math->English leads to reduce 3 points, but the
word "English" appears earlier than the word "Math", so we choose the first order. That is so-called alphabet order. 题意:
有n个作业,每个作业有一个截止日期和一个完成所需时间,如果一个作业迟交x天,就要扣除x个学分,求扣除作业最小的写作业顺序,如果多个方案,输出字典序最小的那个。
思路:
状压dp
dp[i][j]:j是状压后的数字,二进制位上,1表示以完成,0表示未完成。i表示i是j状态最后一个完成的作业。
用一个pre数组记录完成作业的顺序。
状态转移方程请详见代码。
此题的要点是在j状态下,dp数组增加一维i来记录最后一个完成的作业,用以记录作业完成的顺序。
当然其他博主有一维的写法,不过私以为我的代码更容易理解,不过时间复杂度也多了一个n。
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#define fuck(x) cout<<#x<<" = "<<x<<endl;
#define ls (t<<1)
#define rs ((t<<1)+1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = ;
const int inf = 2.1e9;
const ll Inf = ;
const int mod = ;
const double eps = 1e-;
const double pi = acos(-);
int n;
char name[][];
int d[],c[];
int dp[][];
int f[];
struct node{
int x,y;
};
node pre[][];
stack<int>st;
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=;i<n;i++){
scanf("%s%d%d",name[i],&d[i],&c[i]);
}
memset(dp,0x3f,sizeof(dp));
memset(f,,sizeof(f));
memset(pre,-,sizeof(pre)); dp[][]=;
int m=(<<n)-;
for(int i=;i<m;i++){
for(int j=;j<n;j++){
if(i&(<<j)){continue;}
int k=i|(<<j);
f[k]=f[i]+c[j];
for(int t=;t<n;t++){
if(dp[j][k]>=dp[t][i]+max(,f[k]-d[j])){
dp[j][k]=dp[t][i]+max(,f[k]-d[j]);
pre[j][k]=node{t,i};
}
}
}
}
int ans=inf,s;
for(int i=;i<n;i++){
if(ans>=dp[i][m]){ans=dp[i][m];s=i;}
}
printf("%d\n",ans);
node exa=node{s,m};
while(true){
if(exa.y==){break;}
st.push(exa.x);
exa=pre[exa.x][exa.y];
}
while(!st.empty()){
printf("%s\n",name[st.top()]);
st.pop();
}
}
return ;
}
Doing Homework HDU - 1074 (状压dp)的更多相关文章
- D - Doing Homework HDU - 1074 (状压dp)
题目链接:https://cn.vjudge.net/contest/68966#problem/D 具体思路:我们可以把每个情况都枚举出来,然后用递归的形式求出最终的情况. 比如说 我们要求 10 ...
- Doing Homework(HDU 1074状压dp)
题意:给你n个要做的作业,它们的名字.期限.可完成所需天数(必须连续)在规定期限不能完成要扣分(每天一分)求做作业顺序使扣分最少. 分析:作业数量较少,用状态压缩,做到第i种作业花费的天数dp[i]. ...
- HDU 1074状压DP
Doing Homework Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To ...
- hdu 1074 (状压dp)
题意: 给出几个学科的作业.每个作业剩余的时间.完成每个学科作业的时间.如果在剩余时间内不能完成相应作业 就要扣分 延迟一天扣一分 求最小扣分 解析: 把这些作业进行全排列 求出最小扣分即可 但A( ...
- HDU 4778 状压DP
一看就是状压,由于是类似博弈的游戏.游戏里的两人都是绝对聪明,那么先手的选择是能够确定最终局面的. 实际上是枚举最终局面情况,0代表是被Bob拿走的,1为Alice拿走的,当时Alice拿走且满足变换 ...
- HDU 3001 状压DP
有道状压题用了搜索被队友骂还能不能好好训练了,, hdu 3001 经典的状压dp 大概题意..有n个城市 m个道路 成了一个有向图.n<=10: 然后这个人想去旅行.有个超人开始可以把他扔到 ...
- hdu 2809(状压dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2809 思路:简单的状压dp,看代码会更明白. #include<iostream> #in ...
- hdu 2167(状压dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2167 思路:经典的状压dp题,前后,上下,对角8个位置不能取,状态压缩枚举即可所有情况,递推关系是为d ...
- Engineer Assignment HDU - 6006 状压dp
http://acm.split.hdu.edu.cn/showproblem.php?pid=6006 比赛的时候写了一个暴力,存暴力,过了,还46ms 那个暴力的思路是,预处理can[i][j]表 ...
随机推荐
- 用dbExpress页的SQLConnection1连接sql server2000怎么设置。 [问题点数:0分]
在d7或者c6已经支持了. 贡献一下我的代码吧:dbeConn:= TSQLConnection.Create(nil); dbeConn.Params.Clear; dbeC ...
- html5 服務器發送事件
html5允許頁面獲得來自服務器的更新. 單項消息傳送: 頁面獲得服務器的更新. 以前頁面也可以獲得服務器的更新,但必須詢問服務器是否有可用的更新,而服務器發送事件是單向自動發送. 使用服務器發送事件 ...
- LODOP直接用base64码输出图片
Lodop中的ADD_PRINT_IMAGE,也可以直接输出base64码图片,不用加img标签,如果加了img标签,会被当做超文本对待,受浏览器引擎解析的影响. 什么时候使用base64码直接输出比 ...
- 百度编辑器UEditor使用方法
http://www.cnblogs.com/lionden/archive/2012/07/13/ueditor.html 介绍图片上传:http://uikoo9.com/blog/detail/ ...
- ORACLE 增加两列字段
declare v_cnt number; V_SQL VARCHAR2 (500) := '';begin select count(*) into v_cnt from dual where ex ...
- Vue渲染函数
前面的话 Vue 推荐在绝大多数情况下使用 template 来创建HTML.然而在一些场景中,真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 template 更 ...
- 从身份证号码中获取性别、出生日期、籍贯,并更新mongodb
有这样的需求,人员信息是存在mongodb中,需要存放人员的身份证.性别.出生日期.籍贯等信息.通过脚本导入这些信息,但是只导入了身份证号码,其他信息空缺.现在需要补全其他信息. 其实身份证信息就包含 ...
- Tcp协议的keepalive功能
L:128
- 在 ubuntu 中安装 python3.5、 tornado、 pymysql
一.在 ubuntu 中安装 python3.5 1.首先,在系统中是自带python2.7的.不要卸载,因为一些系统的东西是需要这个的.python2.7和python3.5是可以共存的. 命令如下 ...
- Linux 内存清理
1. Clear PageCache only.sync && echo 1 > /proc/sys/vm/drop_caches2. Clear dentries and in ...