【HDOJ】1074 Doing Homework

最开始以为是贪心,不过写到一半发现不对,看了一下讨论,知道需要使用状态压缩DP,现在还没有使用深搜实现(据说可以)晚上实现一下,道理应该是类似的。前面做八数码,至今未果,就说需要状态压缩。这个太神奇了,因为题目的数据量为15,所以采用移位压缩。即100代表第三个(注意index)的转台为完成。RE了很多次,才发现异或后求得的不是index。。。而且原来的输入数据本身就是字典序,不需要再strcmp,就一直RE在那个if了。

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 
  5 #define MAXNUM  16
  6 #define MAXDP   1<<15
  7 
  8 typedef struct {
  9     int pre;
 10     int reduce;
 11     int complete;
 12 } dp_st;
 13 
 14 dp_st dps[MAXDP];
 15 char  visit[MAXDP];
 16 char  stack[MAXNUM][105];
 17 
 18 typedef struct {
 19     char name[105];
 20     int dead, need;
 21 } homework_st;
 22 
 23 homework_st homeworks[MAXNUM];
 24 
 25 void printCourse(int end) {
 26     int top=0, now=end, id, tmp;
 27 
 28     while (now) {
 29         id = now ^ dps[now].pre;
 30         tmp = 0;
 31         while (id) {
 32             id = id>>1;
 33             ++tmp;
 34         }
 35         strcpy(stack[top++], homeworks[tmp-1].name);
 36         now = dps[now].pre;
 37     }
 38 
 39     while (top) {
 40         --top;
 41         printf("%s\n", stack[top]);
 42     }
 43 }
 44 
 45 int main() {
 46     int case_n, n, len;
 47     int i, j, k, code, tmp, complete, reduce;
 48     //FILE *fout = fopen("data", "w");
 49 
 50     scanf("%d", &case_n);
 51 
 52     while (case_n--) {
 53         scanf("%d%*c", &n);
 54         for (i=0; i<n; ++i)
 55             scanf("%s %d %d", homeworks[i].name, &homeworks[i].dead, &homeworks[i].need);
 56         memset(visit, 0, sizeof(visit));
 57         len = 1<<n;
 58         dps[0].pre = -1;
 59         dps[0].reduce = 0;
 60         dps[0].complete = 0;
 61         visit[0] = 1;
 62         // 0~len-1
 63         for (i=0; i<len-1; ++i) {
 64             for (j=0; j<n; ++j) {
 65                 code = 1<<j;
 66                 // code is not done
 67                 if ((i&code) == 0) {
 68                     k = i|code;
 69                     complete = dps[i].complete + homeworks[j].need;
 70                     tmp = complete - homeworks[j].dead;
 71                     if (tmp < 0)
 72                         tmp = 0;
 73                     reduce = dps[i].reduce + tmp;
 74                     if ( visit[k] ) {
 75                         if (reduce < dps[k].reduce) {
 76                             dps[k].reduce = reduce;
 77                             dps[k].complete = complete;
 78                             dps[k].pre = i;
 79                         }
 80                         /* No need and tmp need to while(){>>1} again
 81                         else if (reduce == dps[k].reduce){
 82                             tmp = dps[k].pre ^ k;
 83                             if (strcmp(homeworks[j].name, homeworks[tmp].name) < 0) {
 84                                 dps[k].reduce = reduce;
 85                                 dps[k].complete = complete;
 86                                 dps[k].pre = i;
 87                             }
 88                         }*/
 89                     } else {
 90                         visit[k] = 1;
 91                         dps[k].reduce = reduce;
 92                         dps[k].complete = complete;
 93                         dps[k].pre = i;
 94                     }
 95                 }
 96             }
 97         }
 98         /*
 99         for (i=0; i<len; ++i)
100             fprintf(fout, "%d: pre=%d,reduce=%d,complete=%d\n", i,dps[i].pre,dps[i].reduce,dps[i].complete);
101         */
102         printf("%d\n", dps[len-1].reduce);
103         printCourse(len-1);
104     }
105 
106     //fclose(fout);
107     return 0;
108 }

 

posted on 2014-04-07 22:56  Bombe  阅读(169)  评论(0编辑  收藏  举报

导航