hdu1074 Doing Homework

这题比较有意思,暴力搜索必然tle,可以用状态压缩dp解决。

我们先不考虑完成所有作业的扣分,而考虑其一个子集的情况。

假设我们得到了完成某子集S对应的作业最少扣分,我们试着向该子集中增加一个元素a,那么我们将得到一个新的集合S1。

从而f(S1) = min(g(S)),  S⊂S, 且#(S) = #(S) - 1。

其中g函数仅依赖于集合S与元素e = (S - S‘)。

如果我们能够在处理S之前将其所有真子集都处理完毕,那么S可以直接由原状态导出。

于是当更新到S为全集的时候,答案也就得到了。

考虑用二进制表示状态,二进制数某一位为1或0代表同位次的元素属于(不属于)该集合。

所有子集的数值大小都比原集合小。

将二进制数从小到大扫描一遍即可。

这就是所谓的状态压缩dp。

复杂度O(n * 2^n)。

acm.hdu.edu.cn/showproblem.php?pid=1074
 
 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4
 5 using namespace std;
 6 typedef __int64 LL;
 7
 8 const int inf = 0x3f3f3f3f;
 9 const int maxn = 100 + 10;
10 const int maxm = 1 << 16;
11
12 char s[20][maxn];
13 int n, high;
14 struct Node{
15     int t, dl;
16 }node[maxn];
17 int dp[maxm];
18 int tc[maxm], pre[maxm], ans[20];
19
20 void print(){
21     printf("%d\n", dp[high]);
22     int p = high, k = 0;
23     while(p){
24         ans[k++] = pre[p];
25         p -= 1 << pre[p];
26     }
27     for(int i = k - 1; i >= 0; i--) puts(s[ans[i]]);
28 }
29
30 int main(){
31     int T;
32     scanf("%d", &T);
33     while(T--){
34         scanf("%d", &n);
35         for(int i = 0; i < n; i++){
36             scanf("%s%d%d", s[i], &node[i].dl, &node[i].t);
37         }
38         high = (1 << n) - 1;
39         memset(dp, inf, sizeof dp);
40         dp[0] = 0;
41         for(int i = 1; i <= high; i++){
42             for(int j = n - 1; j >= 0; j--){
43                 int tem = 1 << j;
44                 //update the current state by enumerating the new element
45                 if(tem & i){
46                     //i is the current state while (i - tem) is the previous state
47                     int p = max(0, node[j].t + tc[i - tem] - node[j].dl);
48                     if(p + dp[i - tem] < dp[i]){
49                         dp[i] = p + dp[i - tem];
50                         tc[i] = node[j].t + tc[i - tem];
51                         pre[i] = j;
52                     }
53                 }
54             }
55         }
56         print();
57     }
58     return 0;
59 }

时间: 2024-10-19 12:13:09

hdu1074 Doing Homework的相关文章

状态压缩-----HDU1074 Doing Homework

HDU1074 Doing Homework 题意:给了n个家庭作业,然后给了每个家庭作业的完成期限和花费的实践,如果完成时间超过了期限,那么就要扣除分数,然后让你找出一个最优方案使扣除的分数最少,当存在多种方案时,输出字典序最小的那种,因为题意已经说了家庭作业的名字是按照字典序从小到大输入的,所以处理起来就好多了. 分析:此题的关键是如何记录路径,具体看代码 1 #include <iostream> 2 #include <cstdio> 3 #include <cstr

[HDU1074]Doing Homework (状压DP)

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 t

HDU1074 Doing Homework 状态压缩dp

题目大意: 根据完成任务的截止时间,超时一天罚1分,求完成所有任务后的最小罚时 这里n最大为15,可以利用状态压缩来解决问题 1 /* 2 首先要明白的一点是状态1/0分别表示这件事做了还是没做 3 而1/0的位置表示这是哪一件事 4 比如说 5 可以表示为101,那么表示第一个和第三个任务已经完成 5 而dp[5]表示第一个和第三个任务完成所花费的最短时间 6 而状态5(101)是从状态1(001)或者状态4(100)转移过来的 7 也就是说我们总是可以通过一个较小的状态不断递推一个较大状态的

「kuangbin带你飞」专题十二 基础DP

layout: post title: 「kuangbin带你飞」专题十二 基础DP author: "luowentaoaa" catalog: true tags: mathjax: true - kuangbin - 动态规划 传送门 A.HDU1024 Max Sum Plus Plus 题意 给你N个数,然后你分成M个不重叠部分,并且这M个不重叠部分的和最大. 思路 动态规划最大m字段和,dp数组,dp[i][j]表示以a[j]结尾的,i个字段的最大和 两种情况:1.第a[j

D - Doing Homework HDU1074 ( 动态规划 + 状态压缩 )

D - Doing Homework Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Practice HDU 1074 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

HDU1074:Doing Homework(状压DP)

Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 15868    Accepted Submission(s): 7718 Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he has a l

HDU 1789 Doing Homework again(贪心)

Doing Homework again 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 deadlin

uva 1489 - Math teacher&#39;s homework(数位dp)

题目链接:uva 1489 - Math teacher's homework 题目大意:给定n,k,以及序列m1,m2,-,mn, 要求找到一个长度为n的序列,满足0<=xi<=mi, 并且x1XORx2XOR-XORxn=k 解题思路:数位dp,在网上看了别人的代码,高大上... 假设有二进制数 k : 00001xxxx mi:0001xxxxx, 那么对于xi即可以满足任意的x1XORx2XOR-XORxi?1XORxi+1XOR-XORxn,根据这一点进行数位dp. dp[i][j]

HDU 1074 Doing Homework 状压DP

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 r