zoukankan      html  css  js  c++  java
  • HDU 4791 Alice's Print Service(2013长沙区域赛现场赛A题)

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

    解题报告:打印店提供打印纸张服务,需要收取费用,输入格式是s1 p1 s2 p2 s3 p3...表示打印区间s1到s2张纸的单价是p1,打印区间s2 到s3的单价是p2....最后是sn到无穷大的单价是pn,让你求打印k张纸的总费用最少是多少?有m次查询.

    因为s1*p1 > s2 * p2 > s3*p3......,很显然,加入k所在的那个区间是第x个区间,那么最低费用要么是k * px,要么多打印一点,多打印的时候可以确定打印的张数一定是x区间后面的某个区间的左端点的张数,因为已经超出我要打印的张数了,所以任意一个区间的中间的数量一定会大于这个区间的左端点的数量,所以,现在我要决定的就是打印多少张了,很显然,打印的张数要么是我现在输入的k张,要么是某个区间的左端点的值.但因为数据是10^5,所以我可以从后往前扫一遍,就可以确定这个可能导致费用最低的区间是哪个区间.然后就是确定k应该属于哪个区间的时候用二分查找就行了.

     1 #include <cstdio>
     2 #include <cstring>
     3 #include<iostream>
     4 #include <algorithm>
     5 
     6 using namespace std;
     7 #define LL __int64//待会记得改
     8 #define maxn 100010
     9 struct node
    10 {
    11     LL tot,p;
    12     LL s1,s2;
    13     int next;
    14 }all[maxn];
    15 int find_s1(LL d,node* temp,int l,int r)
    16 {
    17     while(l < r)
    18     {
    19         int mid = (l + r) / 2;
    20         if(d <= temp[mid].s1) r = mid;
    21         else if(d > temp[mid].s1) l = mid + 1;
    22     }
    23     if(!(d >= temp[l].s1 && d < temp[l].s2)) return l-1;
    24     return l;
    25 }
    26 LL Min(LL a,LL b)
    27 {
    28     return a <= b? a:b;
    29 }
    30 LL Max(LL a,LL b)
    31 {
    32     return a >= b? a:b;
    33 }
    34 int main()
    35 {
    36 //    freopen("in","r",stdin);
    37     int T,n,m;
    38     scanf("%d",&T);
    39     LL d,s = 0,t1,t2;
    40     while(T--)
    41     {
    42         scanf("%d%d",&n,&m);
    43         scanf("%I64d",&s);
    44         for(int i = 0;i < n-1;++i)
    45         {
    46             scanf("%I64d%I64d",&all[i].p,&all[i].s2);
    47             all[i].s1 = s;
    48             all[i].tot = all[i].s1 * all[i].p;
    49             s = all[i].s2;
    50         }
    51         all[n-1].s1 = s;
    52         all[n-1].s2 = 0x7fffffff;
    53         scanf("%I64d",&all[n-1].p);
    54         all[n-1].tot = all[n-1].p * all[n-1].s1;
    55         all[n-1].next = n;
    56         all[n] = all[n-1];
    57         int pp = n;
    58         for(int i = n-1;i >= 0;--i)
    59         {
    60             all[i].next = pp;
    61             if(all[pp].tot > all[i].tot) pp = i;
    62         }
    63         for(int i = 0;i < m;++i)
    64         {
    65             scanf("%I64d",&d);
    66             int q = find_s1(d,all,0,n-1);
    67             t1 = all[q].p * d;
    68             if(all[q].f != n-1)    //前n-1个
    69             {
    70                 t2 = all[all[q].next].p * Max(all[all[q].next].s1,d);
    71                 printf("%I64d
    ",Min(t1,t2));
    72             }
    73             else printf("%I64d
    ",t1);    //第n个的情况
    74         }
    75     }
    76     return 0;
    77 }
    View Code
  • 相关阅读:
    课堂作业
    读书计划
    软件工程----11软件演化
    软件工程----10软件测试
    软件工程概论第五章--软件工程中的形式化方法
    软件工程概论第四章--需求工程
    软件工程概论第三章--软件项目管理
    软件工程概论第二章--软件过程
    软件工程概论第一章--概述
    在jsp里面如何用按钮跳转(转自http://oracleabc-126-com.iteye.com/blog/941739)自己留着学
  • 原文地址:https://www.cnblogs.com/xiaxiaosheng/p/4129231.html
Copyright © 2011-2022 走看看