• ZOJ 3703 Happy Programming Contest (01背包,稍微加点处理)


    先按做完题目的时间排序,在确定自己要做哪些题后,先做时间短的,这样能保证等的时间是最短的,在这里,能保证罚时会是最少的。然后0-1背包,0-1背包时先只管价值最大,在背包完后当价值一样时,再管题目做的多,题目数量一样时再管罚时少。

    贴代码,代码中有注释:

    View Code
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define INF 0x7fffffff//int类型中最大的正整数
     5 using namespace std;
     6 struct node1
     7 {
     8     int time,value;//时间,价值
     9     bool operator < (const node1 & o)const
    10     {
    11         if(time < o.time) return true;
    12         else return false;
    13     }
    14 } p[55];
    15 struct node2
    16 {
    17     int value,q,endtime,penalty;//价值,题目数量,结束时间,罚时
    18 } f[1005];//f[i]中的i表示为时间限制为i
    19 int main()
    20 {
    21 //    freopen("in.cpp","r",stdin);
    22     int r;
    23     scanf("%d",&r);
    24     while(r--)
    25     {
    26         int l,num;
    27         scanf("%d%d",&l,&num);
    28         for(int i=0; i<num; ++i)
    29             scanf("%d",&p[i].time);
    30         for(int i=0; i<num; ++i)
    31             scanf("%d",&p[i].value);
    32         sort(p,p+num);//排序
    33         for(int i=0; i<=l; ++i)//0-1背包的恰好装满型
    34         {
    35             f[i].value = -INF;//初始值为负无穷
    36             f[i].q = 0;
    37             f[i].endtime= 0;
    38             f[i].penalty = 0;
    39         }
    40         f[0].value = 0;//只有容量为0的初始值为0
    41         for(int i=0; i<num; ++i)
    42         {
    43             for(int j=l; j >= p[i].time; --j)
    44             {
    45                 int w =j-p[i].time;
    46                 if(f[w].value + p[i].value > f[j].value)
    47                 {
    48                     f[j].value = f[w].value + p[i].value;
    49                     f[j].q = f[w].q +1;
    50                     f[j].endtime = f[w].endtime + p[i].time;//该题的结束时间
    51                     //做到这个题的罚时=做到上题的罚时加上这题的结束时间
    52                     f[j].penalty = f[w].penalty + f[j].endtime;
    53                 }
    54             }
    55         }
    56         node2 ans= {0,0,0};
    57         for(int i=0; i<=l; ++i)
    58         {
    59             if(f[i].value > ans.value)//价值最大优先
    60                 ans = f[i];
    61             else if(f[i].value == ans.value )//价值一样
    62             {
    63                 if(f[i].q > ans.q)//做的题多的优先
    64                     ans = f[i];
    65                 else if(f[i].q  ==  ans.q && f[i].penalty < ans.penalty)//做的题数量一样后
    66                     //罚时少的优先
    67                     ans = f[i];
    68             }
    69         }
    70         printf("%d %d %d\n",ans.value,ans.q,ans.penalty);//输出结果
    71     }
    72     return 0;
    73 }
  • 相关阅读:
    Cookie和Session的那些事儿
    【IScroll深入学习】解决IScroll疑难杂症
    使用 iscroll 实现焦点图无限循环
    jquery.mobiscroll仿Iphone ActionSheet省市区联动
    mobiscroll之treelist使用
    jQuery.extend 函数详解
    jQuery插件开发精品教程,让你的jQuery提升一个台阶
    用js实现动画效果核心方式
    js特效,加速度,图标跳动
    详解用CSS3制作圆形滚动进度条动画效果
  • 原文地址:https://www.cnblogs.com/allh123/p/3065603.html
Copyright © 2020-2023  润新知