• 【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
    ", 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
    ", i,dps[i].pre,dps[i].reduce,dps[i].complete);
    101         */
    102         printf("%d
    ", dps[len-1].reduce);
    103         printCourse(len-1);
    104     }
    105 
    106     //fclose(fout);
    107     return 0;
    108 }
  • 相关阅读:
    spoj 7001 Visible Lattice Points莫比乌斯反演
    codeforces 446C DZY Loves Fibonacci Numbers 数论+线段树成段更新
    fzu 1753 质因数的应用
    hud 4746 莫比乌斯反演
    hdu 1695 容斥原理或莫比乌斯反演
    hdu 4741 Save Labman No.004异面直线间的距离既构成最小距离的两个端点
    codeforces练习
    年底Android面试整理(附答案)
    最近Android真的凉凉了?
    Android 应用防止被二次打包指南
  • 原文地址:https://www.cnblogs.com/bombe1013/p/3651009.html
Copyright © 2020-2023  润新知