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. 22-reverseString-Leetcode

    思路:so easy class Solution { public: string reverseString(string s) { int n = s.size(); for(int i=0;i ...

  2. PhantomJS的安装和使用

    PhantomJS是一个无界面的.可脚本编程的WebKit浏览器引擎,它原生支持多种Web标准:DOM操作.CSS选择器.JSON.Canvas以及SVG.Selenium支持PhantomJS,这样 ...

  3. 🏆【Alibaba中间件技术系列】「Sentinel技术专题」分布式系统的流量防卫兵的基本介绍(入门源码介绍)

    推荐资料 官方文档 官方demo Sentinel 是什么? 随着微服务的流行,服务和服务之间的稳定性变得越来越重要.Sentinel 以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度保护 ...

  4. Hadoop 相关知识点(二)

    1.HDFS副本机制 Hadoopde 默认副本布局策略是: (1)在运行客户端的节点上放置第一个副本(如果客户端运行在集群之外,就随机选择一个节点,不过系统会避免选择那些存储太满或者太忙的节点): ...

  5. Scala(八)【面向对象总结】

    面向对象总结 面向对象 1.scala包 1.声明包 1.在文件第一行通过package 包名 2.package 包名{ .... } 第二种方法,包名只能在target目录才能看到 2.导入包 1 ...

  6. 学习Vue源码前的几项必要储备(二)

    7项重要储备 Flow 基本语法 发布/订阅模式 ES6+ 语法 原型链.闭包 函数柯里化 event loop 接上讲 聊到了ES6的几个重要语法,加下来到第四点继续开始. 4.原型链.闭包 原型链 ...

  7. 【STM8】SPI通讯

    这篇内容有点长,如果有人想透过我的博客学习STM8的SPI,那是我的荣幸 首先我要先说大纲,这样大家心里比较有底,可以把精力都用在SPI理解上 [SPI初步介绍]:介绍SPI如何接线.名称解释.通讯注 ...

  8. html框架frame iframe

    框架 通过使用框架,你可以在同一个浏览器窗口中显示不止一个页面.没分HTML文档称作一个框架. 缺点: 开发人员必须同时跟踪更多的HTML文档 很难打印整张页面 框架结构标签(<frameset ...

  9. 侵入式&非侵入式

    侵入式设计 引入了框架,对现有的类的结构有影响:即需要实现或继承某些特定类. 例如:Struts框架 非侵入式设计 引入了框架,对现有的类结构没有影响. 例如:Hibernate框架 / Spring ...

  10. 【Linux】【Shell】【text】文本处理工具

    文本查看及处理工具:wc, cut, sort, uniq, diff, patch wc:word count wc [OPTION]... [FILE]... -l: lines -w:words ...