zoukankan      html  css  js  c++  java
  • hdu1074Doing Homework(状压dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1074

    题意:n个作业,截止时间di,需要ci时间做完,每超过截止时间一天罚一分,问最少罚多少分。

    1<=N<=15,状态压缩。

     1 #include<cstdio>
     2 #include<cstring>
     3 const int maxn=16;
     4 int dp[1<<maxn],t[1<<maxn],pre[1<<maxn];
     5 int d[maxn],c[maxn];
     6 char s[maxn][120];
     7 int n;
     8 void print(int x)
     9 {
    10     if(x==0) return ;
    11     print(pre[x]);
    12     x-=pre[x];
    13     for(int i=0;i<n;i++)
    14         if(x&1<<i) puts(s[i]);
    15 }
    16 int main()
    17 {
    18     int tt;
    19     scanf("%d",&tt);
    20     while(tt--)
    21     {
    22         int cost;
    23         scanf("%d",&n);
    24         memset(dp,0x3f,sizeof(dp));   //之前还没这么用过,一直以为只能赋0和1
    25         for(int i=0;i<n;i++)
    26             scanf("%s%d%d",s[i],&d[i],&c[i]);
    27         dp[0]=t[0]=0;  //初始罚分为0;
    28         int m=1<<n;     
    29         for(int i=1;i<m;i++)   //枚举所有补过的作业状态,1为补过,0为未补
    30             for(int j=0;j<n;j++)   //按位寻找合法前驱
    31         {
    32             if((i&1<<j)==0) continue;
    33             int k=i-(1<<j);  //k是前驱状态
    34             t[i]=t[k]+c[j];  //从状态k到i(这次做j号作业),到此一共耗时为t[k]+c[j]
    35             cost=t[i]-d[j]>0?t[i]-d[j]:0;  //计算罚分
    36             if(dp[i]>=dp[k]+cost)   // 用>=是为了最小字典序
    37             {
    38                 dp[i]=dp[k]+cost;
    39                 pre[i]=k;   //记录前驱状态
    40             }
    41         }
    42         printf("%d
    ",dp[m-1]);
    43         print(m-1);  //递归打印
    44     }
    45 }
  • 相关阅读:
    SVN客户端的安装和使用
    SVN服务器的安装和使用
    ssh port forwarding
    mysql 索引
    ssh forwarding 配置
    pymongo collection.save 问题
    linux 实现VLAN
    linux 硬件中断调节
    M2Crypto
    python 时间四舍五入
  • 原文地址:https://www.cnblogs.com/yijiull/p/6606483.html
Copyright © 2011-2022 走看看