hdu 1074
地址:http://acm.hdu.edu.cn/showproblem.php?pid=1074
题意:有很多作业,没有在规定时间内完成要扣分,一天一分,求最小扣分!
mark:wa了两次,傻了。。把题意理解错了。是超过期限一天就扣一分!!!
状态压缩dp。dp[i]代表第i个状态的最小罚时,由于本题要输出顺序,所以给dp加上了一个变量,是该状态是由哪个状态来的。
代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> const int M = (1 << 15); typedef struct { int re; int now; int pos; }DP; typedef struct { char name[110]; int de; int day; }sub; DP dp[M+10]; sub s[20]; int main() { int t,n,m; int i,j,k; int flag[20]; scanf("%d", &t); while(t-- && scanf("%d", &n)) { m = (1 << n); for(i = n; i > 0; i--) scanf("%s%d%d", s[i].name, &s[i].de, &s[i].day); dp[0].re = dp[0].pos = dp[0].now = 0; for(i = 1; i < m; i++) { dp[i].now = 0; for(j = 0; j < n; j++) if(i & (1 << j)) dp[i].now += s[n-j].day; dp[i].re = 0x7fffffff; } for(i = 0; i < m-1; i++) { for(j = 0; j < n; j++) { k = (1 << j); if(!(i & k)) { int sum; sum = dp[i].now+s[n-j].day-s[n-j].de; if(sum < 0) sum = 0; if(dp[i | k].re > dp[i].re+sum) { dp[i | k].re = dp[i].re+sum; dp[i | k].pos = n-j; } } } } printf("%d\n", dp[m-1].re); i = m-1; for(j = n; j > 0; j--) { flag[j] = dp[i].pos; i ^= (1 << (n-dp[i].pos)); } for(i = 1; i <= n; i++) printf("%s\n", s[flag[i]].name); } return 0; }