HDU 1074 Doing Homework(DP状态压缩)
2018-05-14 18:01
363 查看
题意:有n门功课需要完成,每一门功课都有时间期限以及你完成所需要的时间,如果完成的时间超出时间期限多少单位,就会被减多少学分,问以怎样的功课完成顺序,会使减掉的学分最少,有多个解时,输出功课名字典序最小的一个。
作业最多只有15个,容易想到是状态压缩 dp[i]表示i对应状态的最小扣分 i转换为二进制后为1的位表明该位对应的作业已经做了,为0的位没做。
dp[i] = min{dp[k] + cost | k为将某一位变成1后等于 i 的状态}
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int N = 16; struct Node { char str[109]; int want, need; }node ; struct DP // 状态 { int now, sum, pre, pos; // 当前状态的时间,总惩罚,前一个选择,当前选择 }dp[1<<N]; void put_ans(int x) { if(dp[x].pre != -1) { put_ans(dp[x].pre); printf("%s\n", node[dp[x].pos].str); } } int main () { int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%s%d%d", node[i].str, &node[i].want, &node[i].need); dp[0].now = dp[0].sum = 0; dp[0].pre = dp[0].pos = -1; int m = (1<<n)-1; for(int i=1; i<=m; i++) { dp[i].sum=0x3f3f3f3f; for(int j=0; j<n; j++) { if((1<<j) & i) { int k = i - (1<<j); int v = dp[k].now + node[j].need - node[j].want; v = max(v, 0); if(dp[i].sum >= dp[k].sum+v)//必须有等号,这样保持字典序 { dp[i].sum = dp[k].sum + v; dp[i].now = dp[k].now + node[j].need; dp[i].pre = k; dp[i].pos = j; } } } } printf("%d\n", dp[m].sum); put_ans(m); } return 0; }
相关文章推荐
- 【状态压缩dp】HDU - 1074 Doing Homework
- HDU 1074-Doing Homework(状态压缩dp)
- hdu 1074 doing homework(状态压缩dp)
- hdu-1074 Doing Homework(状态压缩DP)
- HDU 1074 Doing Homework【状态压缩DP】
- hdu 1074 Doing Homework (状态压缩 dp)
- HDU 1074 Doing Homework【状态压缩DP】
- HDU 1074 Doing Homework (二进制状态压缩,状压dp)
- HDU1074 Doing Homework 状态压缩dp
- HDU 1074 Doing Homework(状态压缩DP)
- HDU 1074 Doing Homework (状态压缩DP)
- Doing Homework HDU - 1074 (状态压缩DP) HQG_AC的博客
- HDU-1074 Doing Homework 状态压缩DP
- HDU 1074:Doing HomeWork(状态压缩DP)
- hdu1074 Doing Homework(状态压缩DP Y=Y)
- HDU 1074 Doing Homework (状态压缩DP)
- HDU 1074 Doing Homework (状态压缩DP)
- HDU 1074 Doing Homework(状态压缩dp)
- !HDU 1074 Doing Homework--DP--(状态压缩)
- HDU1074 Doing Homework 状态压缩dp