题目大意
你要完成n份作业(n最大15)每份作业有需要完成的时间和时限,不能在要求的时间内完成每晚一个时间单位扣一分,问扣分最少是多少 在扣分最少的情况下 要求输出完成顺序 要输出所有可能种字典序排的一份
题解
乍一看之下,简单 简单~ 不就是按时限排个序就知道最小值了吗 唉等等 要求输出字典序最小的情况,这就有些意思了 因为这时候时限小的可能由于字典序问题不一定排在前面 举例来说
math 20 1
se 5 1
这种情况下时限并没有任何意义 不能简单排序了之
那要怎么办呢?考虑到n给的很小,我一下子之前做过想到了状压dp 对于每个状态,搜索置为1的看看能不能从那个状态过来,这样遍历即可 由于输入自然的保证了顺序 我们只需要搜索时倒着搜索就可以保证字典序了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
   | #include<cstdio> #include<algorithm> #include<string> #include<cstring> #include<stack> using namespace std; struct subject{     string classname;     int endtime,lasttime; }; subject classes[20]; struct node{     int nowtime,score,lastindex; }dp[1<<17]; int main(){     int T;     scanf("%d",&T);     while(T--){         int n;         scanf("%d",&n);         char tmp[120];         for(int i=0;i<n;++i){             scanf("%s%d%d",tmp,&classes[i].endtime,&classes[i].lasttime);             classes[i].classname=tmp;         }         memset(dp,0,sizeof(dp));         int s=1<<n;         for(int i=1;i<s;++i){             dp[i].score=0x3fffffff;             for(int j=n-1;j>=0;--j){                 int t=1<<j;                 if(i&t){                     int addscore=dp[i&(~t)].nowtime+classes[j].lasttime-classes[j].endtime;                     if(addscore<0){                         addscore=0;                     }                     if(dp[i&(~t)].score+addscore<dp[i].score){                         dp[i].score=dp[i&(~t)].score+addscore;                         dp[i].nowtime=dp[i&(~t)].nowtime+classes[j].lasttime;                         dp[i].lastindex=j;                     }                 }             }         }         stack<string> order;         int t=(1<<n)-1;         printf("%d\n",dp[t].score);         while(t){             order.push(classes[dp[t].lastindex].classname);             t&=(~(1<<dp[t].lastindex));         }         while(!order.empty()){             printf("%s\n",order.top().c_str());             order.pop();         }     }     return 0; }
   |