HDU 1074 Doing Homework 状态压缩DP
Posted EricJeffrey
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 1074 Doing Homework 状态压缩DP相关的知识,希望对你有一定的参考价值。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1074
题目大意:小明打完比赛回来补作业,N个作业每个作业有 名字,截止日期,完成所需时间 三个属性,如果完成时间>截止日期,就会被扣分,多一天扣一分。现在你帮他安排做作业计划。N < 15
解题思路:其实很明确的是这是个决策性问题。每次都要做一个决策,从N个作业中选出来一个来做,那么问题就是多个决策,每个决策有N种可选,如何做出决策? 那么就是典型的DP了。
状态:已经完成了m个作业------->>接下来要做第m+1个作业
转移:可以从已经做得作业中选出来m个,看已用时间,然后计算做第m+1个作业的扣分情况。
那么dp[S] :=完成S集合中的作业所扣的分数最小值。
dp[S] = min(dp[S^X] + S^X用时-第X个作业截止日期) X 为1 ~ N中的任意一个作业且 S & X != 0
由于N < 15,所以可以采用状态压缩方式,每一位表示一个作业,1为选择了,0为未选择。
代码:
1 const int maxn = 20; 2 const int maxm = (1 << 15) + 5; 3 struct sub{ 4 int dl, ti, name; 5 }; 6 char str[maxn][105]; 7 sub subs[maxn]; 8 int n; 9 int csb[maxn], dp[maxm], tis[maxm], pre[maxm], curs[maxm]; 10 11 void solve(){ 12 for(int i = 1; i <= n; i++) csb[i] = 1 << (i - 1); 13 14 memset(dp, 0x3f, sizeof(dp)); 15 memset(tis, 0, sizeof(tis)); 16 memset(pre, 0, sizeof(pre)); 17 18 const int cnt = 1 << n; 19 for(int i = 1; i < cnt; i++){ 20 int x = i, st = 1; 21 while(x){ 22 tis[i] += (x & 1) * subs[st].ti; 23 x >>= 1; st++; 24 } 25 } 26 dp[0] = 0; 27 for(int i = 1; i < cnt; i++){ 28 for(int j = 1; j <= n; j++){ 29 int tmp = tis[csb[j] ^ i] + subs[j].ti - subs[j].dl; 30 if(tmp < 0) tmp = 0; 31 if((i & csb[j]) && dp[csb[j] ^ i] + tmp <= dp[i]){ 32 dp[i] = dp[csb[j] ^ i] + tmp; 33 pre[i] = csb[j] ^ i; 34 curs[i] = j; 35 } 36 } 37 } 38 printf("%d\n", dp[cnt - 1]); 39 stack<int> s; 40 int st = cnt - 1; 41 int sst = curs[st]; 42 while(st > 0){ 43 s.push(subs[sst].name); 44 st = pre[st]; 45 sst = curs[st]; 46 } 47 while(!s.empty()){ 48 int u = s.top(); s.pop(); 49 printf("%s\n", str[u]); 50 } 51 52 return; 53 } 54 int main(){ 55 int T; 56 scanf("%d", &T); 57 while(T--){ 58 scanf("%d", &n); 59 for(int i = 1; i <= n; i++){ 60 scanf("%s %d %d", str[i], &subs[i].dl, &subs[i].ti); 61 subs[i].name = i; 62 } 63 solve(); 64 } 65 }
题目:
Doing Homework
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 9876 Accepted Submission(s): 4725
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.
以上是关于HDU 1074 Doing Homework 状态压缩DP的主要内容,如果未能解决你的问题,请参考以下文章
[2016-03-28][HDU][1074][Doing Homework]