{{{ #!cplusplus /* hdu1074 ymc 2008/10/9 题目大意 你n个任务,每个任务完完成的最后期限d和所需的时间c。 如果某个任务的完成时间超过了最后期限d,则要惩罚,惩罚的数值为超过的天数。 求完成这n个任务的最小惩罚数值以及完成的次序。 分析与解题思路: 用n位表示任务的完成状态,对应位上为1表示该任务已经完成,否则表示未完成。 每个状态有三个数据,分别是达到该状态的最小惩罚数值,达到该状态总共所需的时间,已经到达该 状态的最后完成个一个任务。 结构体 struct Status { int reduce; //惩罚时间 int time;//总共花费时间 int last;//最后一个完成的任务 }; Status ans[M]表示所有的状态 则状态转移方程为 ans[next].reduce=min{ans[k].reduce+reduce[i]}; 其中k为第i个任务未完成,完成的i个任务后,状态k转变为状态next。 */ #include #include using namespace std; const int N=15; const int M=65536; char s[N][110]; int d[N],c[N]; int n; struct Status { int reduce; //惩罚时间 int time;//总共花费时间 int last;//最后一个完成的任务 }; Status ans[M]; void Init() { scanf("%d",&n); for(int i=0;i>i); if((tmp&1)==0)//第i个任务未完成 { next=k+(1<d[i]) tmp+=ans[next].time-d[i]; if(ans[next].reduce==-1||ans[next].reduce>tmp) { ans[next].reduce=tmp; ans[next].last=i; } } ans[k].reduce=-1;//当前状态以后不会在用到。 } } void Output() { int t; t=(1<=0)//生成输出序列 { out[k++]=ans[t].last; t=t-(1<=0;k--) printf("%s\n",s[out[k]]); } int main() { int test; scanf("%d",&test); while(test-->0) { Init(); DP(); Output(); } } }}}