zoukankan      html  css  js  c++  java
  • hdu 1074 状态压缩

    http://acm.hdu.edu.cn/showproblem.php?pid=1074

    我们可以断定状态的终止态一定是n个数全部选完的情况,那么它的前一个状态是什么呢,一定是剔除任一门课程后的n种状态。

    例如

    dp[全选了]=min{(dp[除了math都做了]+math的超时天数),(dp[除了computer都做了]+computer的超时天数),(dp[除了english都做了]+english的超时天数)}那么接下来的dp状态依然如此。

    好了,接下来,我们该如何去思考了,这个题目共有2^15种可能情况,对此我们通过位运算方法降低它的维度。

    二进制的每一位代表一门课,它的组合可以完成展示出所有的状态。

    最后我们应该去思考一个问题,顺序的问题,我们知道,第一次取得时候,一定只有一个课程,如果我们以

    1 int bit = 1<<n;
    2 for(int i = 1;i<bit;i++)

    能否确保某一个状态的前一个都完全包含,你可以自己去检验,是完全满足的.

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int MAXN = (1<<15)+10;
     7 const int INF = 0x3f3f3f;
     8 struct node
     9 {
    10     char str[105];
    11     int d;//the deadtime
    12     int c;//need spend time
    13 };
    14 node nd[20];
    15 int dp[MAXN],pre[MAXN],t[MAXN];
    16 void output(int x)
    17 {
    18     if(!x)
    19         return ;
    20     output(x-(1<<(pre[x]-1)));
    21     printf("%s
    ",nd[pre[x]].str);
    22 }
    23 int main()
    24 {
    25     int cas,n;
    26     scanf("%d",&cas);
    27     while(cas--)
    28     {
    29         memset(t,0,sizeof(t));
    30         memset(pre,0,sizeof(pre));
    31         //memset(dp,0,sizeof(dp));
    32         scanf("%d",&n);
    33         for(int i = 1;i<=n;i++)
    34         {
    35             scanf("%s%d%d",nd[i].str,&nd[i].d,&nd[i].c);
    36         }
    37        /* for(int i = 1;i<=n;i++)
    38         {
    39             printf("%s %d %d
    ",nd[i].str,nd[i].d,nd[i].c);
    40         }*/
    41         int bit = 1<<n;
    42         for(int i = 1;i<bit;i++)
    43         {
    44             dp[i] = INF;
    45             for(int j = n;j>=1;j--)
    46             {
    47                 int temp = 1<<(j-1);
    48                 if(!(temp&i))
    49                     continue;
    50                 else
    51                 {
    52                     int dist = (t[i-temp]+nd[j].c-nd[j].d);
    53                     if(dist > 0)
    54                     {
    55                         if(dp[i]>(dp[i-temp]+dist))
    56                         {
    57                             t[i]=t[i-temp]+nd[j].c;
    58                             dp[i]=dp[i-temp]+dist;
    59                             pre[i] = j;
    60                         }
    61                     }
    62                     else
    63                     {
    64                         if(dp[i]>dp[i-temp])
    65                         {
    66                             t[i]=t[i-temp]+nd[j].c;
    67                             dp[i]=dp[i-temp];
    68                             pre[i] =j;
    69                         }
    70                     }
    71                 }
    72             }
    73         }
    74         cout<<dp[bit-1]<<endl;
    75         output(bit-1);
    76     }
    77     return 0;
    78 }
  • 相关阅读:
    JVM内存划分
    JVM内存划分
    类装载器学习
    xml文件参数类型有问题
    七牛云的使用
    PyCharm下载及使用
    安装python--环境配置
    软件测试--测试用例
    python selenium ——— 动态id、class定位
    JDBC封装的工具类
  • 原文地址:https://www.cnblogs.com/fancy-itlife/p/5324235.html
Copyright © 2011-2022 走看看