zoukankan      html  css  js  c++  java
  • 杭电1074

    题意:有各种作业,分别给出用时,最后期限,每超一天就扣一分。问做完所有作业的最少扣分及其策略。

    Analyse:自己看的时候是一头雾水,看别人的题解上写的是状态压缩的DP。状态压缩:用0和1表示某一作业的状态,1代表已完成,0代表未动手,一个int足以表示所有的不同状态,例如5中的5表示为二进制就是101,代表第一个作业和第三个作业已经完成,第二个作业未完成,dp[5]就表示假设只有三个作业,只完成第一和第三个作业扣的最少分数。

    View Code
     1 #include<string>
     2 #include<iostream>
     3 #include<vector>
     4 using namespace std;
     5 #define INF 0xfffffff
     6 typedef struct
     7 {
     8     int used_days;//用掉的时间
     9     int preseq;//这个序列之前的序列
    10     int thiswork;
    11     int deducted;//扣除的分数
    12 }sequence;
    13 typedef struct
    14 {
    15     string title;//科目名
    16     int cost;//完成作业花费的时间
    17     int deadline;//最后期限
    18 }subject;
    19 sequence seq[1024*1024];
    20 subject sub[16];
    21 vector<int> list;
    22 int main()
    23 {
    24     int t,n;
    25     int i,j,max;
    26     int temp,deducted,last;
    27     cin>>t;;
    28     while(t--)
    29     {
    30         cin>>n;
    31         for(i=0;i<n;i++)
    32             cin>>sub[i].title>>sub[i].deadline>>sub[i].cost;
    33         max=1<<n;
    34         seq[0].used_days=0;
    35         seq[0].preseq=-1;
    36         seq[0].deducted=0;
    37         for(i=1;i<max;i++)
    38         {
    39             seq[i].deducted=INF;
    40             for(j=n-1;j>=0;j--)
    41             {
    42                 temp=1<<j;
    43                 if(i&temp)
    44                 {
    45                     last=i-temp;
    46                     deducted=seq[last].used_days+sub[j].cost-sub[j].deadline;
    47                     if(deducted<0)
    48                         deducted=0;
    49                     if(seq[last].deducted+deducted<seq[i].deducted)
    50                     {
    51                         seq[i].deducted=seq[last].deducted+deducted;
    52                         seq[i].preseq=last;
    53                         seq[i].used_days=seq[last].used_days+sub[j].cost;
    54                         seq[i].thiswork=j;
    55                     }
    56                 }
    57             }
    58         }
    59         cout<<seq[max-1].deducted<<endl;
    60         for(i=max-1;i!=0;i=seq[i].preseq)
    61             list.push_back(seq[i].thiswork);
    62         for(i=list.size()-1;i>=0;i--)
    63             cout<<sub[list[i]].title<<endl;
    64         list.clear();
    65     }
    66     return 0;
    67 }

     后话:/*后来的专题训练再把这道题做一次,科目输出的顺序总是搞不对,问题在于没注意中间的for是逆序循环的,逆序才能保证最终的顺序是字典序。因为逆序时优先考虑字典序小的先完成。*/

  • 相关阅读:
    HDOJ 1846 Brave Game
    并查集模板
    HDU 2102 A计划
    POJ 1426 Find The Multiple
    POJ 3278 Catch That Cow
    POJ 1321 棋盘问题
    CF 999 C.Alphabetic Removals
    CF 999 B. Reversing Encryption
    string的基础用法
    51nod 1267 4个数和为0
  • 原文地址:https://www.cnblogs.com/ZShogg/p/2675705.html
Copyright © 2011-2022 走看看