zoukankan      html  css  js  c++  java
  • HDU 1074 Doing Homework(DP状态压缩)

    题意:有n门功课需要完成,每一门功课都有时间期限以及你完成所需要的时间,如果完成的时间超出时间期限多少单位,就会被减多少学分,问以怎样的功课完成顺序,会使减掉的学分最少,有多个解时,输出功课名字典序最小的一个。

    作业最多只有15个,容易想到是状态压缩  dp[i]表示i对应状态的最小扣分  i转换为二进制后为1的位表明该位对应的作业已经做了,为0的位没做。

    dp[i] = min{dp[k] + cost | k为将某一位变成1后等于 i 的状态} 

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <vector>
     4 #include <algorithm>
     5 
     6 using namespace std;
     7 
     8 const int N = 16;
     9 struct Node
    10 {
    11     char str[109];
    12     int want, need;
    13 }node[N];
    14 
    15 struct DP // 状态
    16 {
    17     int now, sum, pre, pos; // 当前状态的时间,总惩罚,前一个选择,当前选择
    18 }dp[1<<N];
    19 
    20 void put_ans(int x)
    21 {
    22     if(dp[x].pre != -1)
    23     {
    24         put_ans(dp[x].pre);
    25         printf("%s
    ", node[dp[x].pos].str);
    26     }
    27 }
    28 
    29 int main () {
    30 
    31     int T;
    32     scanf("%d",&T);
    33     while(T--)
    34     {
    35         int n;
    36         scanf("%d",&n);
    37         for(int i=0;i<n;i++)
    38             scanf("%s%d%d", node[i].str, &node[i].want, &node[i].need);
    39         dp[0].now = dp[0].sum = 0;
    40         dp[0].pre = dp[0].pos = -1;
    41         int m = (1<<n)-1;
    42         for(int i=1; i<=m; i++)
    43         {
    44             dp[i].sum=0x3f3f3f3f;
    45             for(int j=0; j<n; j++)
    46             {
    47                 if((1<<j) & i)
    48                 {
    49                     int k = i - (1<<j);
    50                     int v = dp[k].now + node[j].need - node[j].want;
    51                     v = max(v, 0);
    52                     if(dp[i].sum >= dp[k].sum+v)//必须有等号,这样保持字典序
    53                     {
    54                         dp[i].sum = dp[k].sum + v;
    55                         dp[i].now = dp[k].now + node[j].need;
    56                         dp[i].pre = k;
    57                         dp[i].pos = j;
    58                     }
    59                 }
    60             }
    61         }
    62         printf("%d
    ", dp[m].sum);
    63         put_ans(m);
    64     }
    65     return 0;
    66 }
  • 相关阅读:
    Ping pong
    [NOIp2015普及组]推销员
    [模板]树状数组
    [洛谷201704R1]开心派对小火车
    洛谷P3515 [POI2011]Lightning Conductor(决策单调性)
    bzoj1560:[JSOI2009]火星藏宝图(斜率优化)
    (转载)行走在镜面的边缘
    洛谷P4360 [CEOI2004]锯木厂选址(斜率优化)
    洛谷P4072 [SDOI2016]征途(斜率优化)
    洛谷P3648 [APIO2014]序列分割(斜率优化)
  • 原文地址:https://www.cnblogs.com/demian/p/9037398.html
Copyright © 2011-2022 走看看