Doing Homework

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6967    Accepted Submission(s): 3043

Problem Description
Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Every teacher gives him a deadline of handing in the homework. If Ignatius hands in the homework after the deadline, the teacher will reduce his score of the final test, 1 day for 1 point. And as you know, doing homework always takes a long time. So Ignatius wants you to help him to arrange the order of doing homework to minimize the reduced score.
 
Input
The 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.
 
Output
For 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.

 
Author
Ignatius.L
 
思路:状压DP.
一开始想全排列,往这思路上想,这样谁都知道会超时,因为n<15;那么共有pow(2,n)的状态,那么状压dp可解决.
每个状态可由前面多个状态转移而来,所以取最小就是这个状态的最优解,局部最优,最后到整体最优。
状态转移方程和解释具体看下面代码
  1 #include<stdio.h>
2 #include<algorithm>
3 #include<iostream>
4 #include<string.h>
5 #include<stdlib.h>
6 #include<queue>
7 #include<stack>
8 #define sc(x) scanf("%I64d",&x)
9 #define pr(x) printf("%I64d",x);
10 #define prr(x) printf("%I64d\n",x);
11 #define prrr(x) printf(" %I64d",x);
12 #define FOR(i,p,q) for(int i=p;i<=q;i++)
13 int cmp(char *p,char *q);
14 typedef struct pp
15 {
16 int x;
17 int y;
18 char a[200];
19 } ss;
20 ss ab[20];
21 char bc[20][200];
22 const int N=1e9;
23 typedef struct qq
24 {
25 int time;
26 int pre;
27 int no;
28 int cost;
29 } kk;//结构体存这个状态的时间当前加入作业的编号,所罚的时间,和前一个状态
30 kk dp[1<<15+1];
31 using namespace std;
32 int main(void)
33 {
34 int n,i,j,k,p,q;
35 scanf("%d",&k);
36 while(k--)
37 {
38 scanf("%d",&n);
39 for(i=0; i<n; i++)
40 {
41 scanf("%s",ab[i].a);
42 scanf("%d %d",&ab[i].x,&ab[i].y);
43 }
44 for(i=0; i<(1<<15)+1; i++)
45 {
46 dp[i].cost=N;
47 }//初始化
48 dp[0].cost=0;
49 dp[0].pre=-1;
50 dp[0].time=0;//开始的时间等状态
51 for(i=1; i<(1<<n); i++)
52 {
53 for(j=0; j<n; j++)
54 {
55 if(i&(1<<j))//当前这个状态含有第j个作业
56 {
57 if(ab[j].x<=dp[i^(1<<j)].time)//找不含j的前一个状态,并用前一个状态结束时间与第j个作业截至时间比较,然后分情况讨论下
58 {
59 int cc=dp[i^(1<<j)].time-ab[j].x;
60 if(dp[i].cost>dp[i^(1<<j)].cost+cc+ab[j].y)
61 {
62 dp[i].cost=dp[i^(1<<j)].cost+cc+ab[j].y;
63 dp[i].pre=i^(1<<j);
64 dp[i].no=j;
65 dp[i].time=dp[i^(1<<j)].time+ab[j].y;
66 }
67 else if(dp[i].cost==dp[i^(1<<j)].cost+cc+ab[j].y)
68 {
69 if(cmp(ab[j].a,ab[dp[i].no].a)>0)//按字典序排序,将最大的放最后,因为没个都是两两比较
70 {
71 dp[i].cost=dp[i^(1<<j)].cost+cc+ab[j].y;
72 dp[i].pre=i^(1<<j);
73 dp[i].no=j;
74 dp[i].time=dp[i^(1<<j)].time+ab[j].y;
75 }
76 }
77 }
78 else
79 {
80 int uu=ab[j].y+dp[i^(1<<j)].time;
81 int cc=uu-ab[j].x;
82 if(cc<=0)
83 {
84 if(dp[i].cost>dp[i^(1<<j)].cost)
85 {
86 dp[i].cost=dp[i^(1<<j)].cost;
87 dp[i].pre=i^(1<<j);
88 dp[i].no=j;
89 dp[i].time=dp[i^(1<<j)].time+ab[j].y;
90 }
91 else if(dp[i].cost==dp[i^(1<<j)].cost)
92 {
93 if(cmp(ab[j].a,ab[dp[i].no].a)>0)
94 {
95 dp[i].cost=dp[i^(1<<j)].cost;
96 dp[i].pre=i^(1<<j);
97 dp[i].no=j;
98 dp[i].time=dp[i^(1<<j)].time+ab[j].y;
99 }
100 }
101
102 }
103 else
104 {
105 if(dp[i].cost>dp[i^(1<<j)].cost+cc)
106 {
107 dp[i].cost=dp[i^(1<<j)].cost+cc;
108 dp[i].pre=i^(1<<j);
109 dp[i].no=j;
110 dp[i].time=dp[i^(1<<j)].time+ab[j].y;
111 }
112 else if(dp[i].cost==dp[i^(1<<j)].cost+cc)
113 {
114 if(cmp(ab[j].a,ab[dp[i].no].a)>0)
115 {
116 dp[i].cost=dp[i^(1<<j)].cost+cc;
117 dp[i].pre=i^(1<<j);
118 dp[i].no=j;
119 dp[i].time=dp[i^(1<<j)].time+ab[j].y;
120 }
121 }
122
123 }
124
125 }
126 }
127 }
128 }
129 printf("%d\n",dp[(1<<n)-1].cost);
130 int pf=dp[(1<<n)-1].pre;
131 int zk=0;
132 while(zk<n-1)
133 {
134
135 strcpy(bc[zk],ab[dp[pf].no].a);
136 zk++;
137 pf=dp[pf].pre;
138 }
139 for(i=n-2;i>=0;i--)
140 {
141 printf("%s\n",bc[i]);
142 }printf("%s\n",ab[dp[(1<<n)-1].no].a);
143 }
144
145
146 }
147 int cmp(char *p,char *q)
148 {
149 return strcmp(p,q);
150 }

状压DP

Doing Homework(hdu)1074的更多相关文章

  1. (hdu)5391 Zball in Tina Town

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5391 Problem Description Tina Town is a friendl ...

  2. (hdu)1285 确定比赛名次

    Problem Description 有N个比赛队(<=N<=),编号依次为1,,,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接 ...

  3. Doing Homework(HDU 1074状压dp)

    题意:给你n个要做的作业,它们的名字.期限.可完成所需天数(必须连续)在规定期限不能完成要扣分(每天一分)求做作业顺序使扣分最少. 分析:作业数量较少,用状态压缩,做到第i种作业花费的天数dp[i]. ...

  4. (hdu)1042 N! 大数相乘

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1042 Problem Description Given an integer N( ≤ ...

  5. (hdu)5234 Happy birthday 二维dp+01背包

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5234 Problem Description Today is Gorwin’s birt ...

  6. (hdu)4858 项目管理 (vector)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4858 Problem Description 我们建造了一个大项目!这个项目有n个节点,用很多边连接起 ...

  7. 杭电(hdu)ACM 4548 美素数

    美素数 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submis ...

  8. 2019-2020 ICPC, Asia Jakarta Regional Contest A. Copying Homework (思维)

    Danang and Darto are classmates. They are given homework to create a permutation of N integers from  ...

  9. (hdu)1257 最少拦截系统

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1257 Problem Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦 ...

随机推荐

  1. (转载) IBM DB2数据库odbc配置步骤详解

    [IT168 技术] 首先安装IBM DB2 odbc driver 1):可以单独下载DB2 Run-Time Client,大约(86.6m),安装后则odbc驱动程序安装成功.下载地址:ftp: ...

  2. 非标准的xml解析器的C++实现:一、思考基本数据结构的设计

    前言: 我在C++项目中使用xml作为本地简易数据管理,到目前为止有5年时间了,从最初的全文搜索标签首尾,直到目前项目中实际运用的类库细致到已经基本符合w3c标准,我一共写过3次解析器,我自己并没有多 ...

  3. acute

    In Euclidean geometry, an angle is the figure formed by two rays, called the sides of the angle, sha ...

  4. javaIO——输入输出流

    字节流与字符流 File类不支持对文件内容进行相关的操作,所有若要处理文件的内容,则需要通过流操作模式来完成. 流的基本操作步骤: Step1:根据文件路径创建File类对象. Step2:根据字节流 ...

  5. ORACLE 按逗号拆分字符串为多行

    with t as (select '1,2,3,10,11,12' a from dual) select substr(a, decode(level - 1, 0, 0, instr(a, ', ...

  6. Linux学习 - Bash变量

    一.用户自定义变量(本地名) 用户自定义变量只有在当前的shell中生效 1 定义变量 name="zheng huiwei" aa=123 2 变量叠加 aa="$aa ...

  7. Linux基础命令---mirror获取ftp目录

    mirror 使用lftp登录ftp服务器之后,可以使用mirror指令从服务器获取目录   1.语法       mirror [OPTS] [source [target]]   2.选项列表 选 ...

  8. entfrm-boot开发平台一览【entfrm开源模块化无代码开发平台】

    介绍 entfrm-boot是一个以模块化为核心的无代码开发平台,能够让中小企业快速从零搭建自己的开发平台:开箱即用,可插拔可自由组合:以模块化的方式,最大化的代码复用,避免重复开发:无代码可视化开发 ...

  9. 一、手把手教你docker搭建fastDFS文件上传下载服务器

    在搭建fastDFS文件上传下载服务器之前,你需要准备的有一个可连接的linux服务器,并且该linux服务器上已经安装了docker,若还有没安装docker的,先百度自行安装docker. 1.执 ...

  10. 理解css中的 content:" " 是什么意思

    css中的属性是插入生成的内容,它一般与伪元素:befor和 :after 配合使用. content:"." 就表示在需要的地方插入"." 注意:如果已经规定 ...