关闭

hdu 4791 长沙现场赛A题

标签: ACM百度算法编程线段树
1394人阅读 评论(0) 收藏 举报
分类:

题意:打印纸张,随着张数的增加,价格非递增,给出m个询问打印的张数,求最小的花费。

思路:找到张数所在的区间,最大的花费就是该区间的价格*张数,如果要打印多余的张数,就在后面的区间找,因为后边的区间都是张数大于目标张数,所以去区间的最小值,应为价格是非递增的,张数是递增的,所以要找区间的张数*价格的最小值,用线段树就可以。。。

写完了,才想到其实没这么复杂,可以直接从后往前求每个区间右边的最小值,记录一下,直接用就可以了。


#include<stdio.h>
#include<string.h>
const int N=100100;
__int64 cnt[N],num[N];
int n;
struct Tree
{
    int L,R;
    __int64 mw;
}T[N*4];
__int64 min(__int64 a,__int64 b)
{
    if(a>b)return b;
    return a;
}
void buildTree(int L,int R,int id)
{
    T[id].L=L;T[id].R=R;
    if(L==R)
    {
        T[id].mw=cnt[L]*num[L];
        return ;
    }
    int li,ri,mid;
    mid=(L+R)>>1;
    li=id<<1;ri=li|1;
    buildTree(L,mid,li);
    buildTree(mid+1,R,ri);
    T[id].mw=min(T[li].mw,T[ri].mw);
}
__int64 find(int L,int R,int id)
{
    if(T[id].L==L&&T[id].R==R)
        return T[id].mw;
    int li=id<<1,ri=li|1,mid=(T[id].L+T[id].R)>>1;
    if(R<=mid)return find(L,R,li);
    else if(L>mid) return find(L,R,ri);
    else return min(find(L,mid,li),find(mid+1,R,ri));
}
int findnum(__int64 w)
{
    int L,R,mid,flag;
    L=1;R=n;flag=1;
    while(L<=R)
    {
        mid=(L+R)>>1;
        if(num[mid]<=w)
        {
            flag=mid;
            L=mid+1;
        }
        else R=mid-1;
    }
    return flag;
}
int main()
{
    int i,j,m,t;
    __int64 sum,w;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
            scanf("%I64d%I64d",&num[i],&cnt[i]);
        buildTree(1,n,1);
        while(m--)
        {
            scanf("%I64d",&w);
            j=findnum(w);
            if(j==n){printf("%I64d\n",cnt[j]*w);continue;}
            sum=find(j+1,n,1);
            printf("%I64d\n",min(sum,cnt[j]*w));
        }
    }
    return 0;
}




#include<stdio.h>
#include<string.h>
const int N=100005;
__int64 cnt[N],num[N],minw[N];
int n;
__int64 min(__int64 a,__int64 b)
{
    if(a>b)return b;
    return a;
}
int findnum(__int64 w)
{
    int L,R,mid,flag;
    L=1;R=n;flag=1;
    while(L<=R)
    {
        mid=(L+R)>>1;
        if(num[mid]<=w)
        {
            flag=mid;
            L=mid+1;
        }
        else R=mid-1;
    }
    return flag;
}
int main()
{
    int i,j,m,t;
    __int64 w;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
            scanf("%I64d%I64d",&num[i],&cnt[i]);
        minw[n]=num[n]*cnt[n];
        for(i=n;i>=2;i--)
        {
            minw[i-1]=minw[i];
            if(num[i]*cnt[i]<minw[i])
                minw[i-1]=num[i]*cnt[i];
        }
        while(m--)
        {
            scanf("%I64d",&w);
            j=findnum(w);
            if(j==n){printf("%I64d\n",cnt[j]*w);continue;}
            printf("%I64d\n",min(cnt[j]*w,minw[j+1]));
        }
    }
    return 0;
}



2
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

hdu 最大流水题集锦。。。

源自--------------------------------Ice_Crazy(死之前应该会继续更新的。。。) 网络流水题:hdu1532、hdu3549、hdu2732(拆点、经典题目) hdu3572     isap,水,建图:  ...
  • Ice_Crazy
  • Ice_Crazy
  • 2013-08-05 18:22
  • 3900

hdu 1226 搜索好题 帅呆了的题目

超级密码 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1460  ...
  • hnust_xiehonghao
  • hnust_xiehonghao
  • 2013-05-30 11:58
  • 1782

HDU6040(思维题)

题意:通过题目所给函数求出a数组,然后根据b数组排a数组。ai必须是a数组中第(bi+1)大的数。 分析:先通过下标对b数组排序。然后扫一遍b数组,如果相邻两个位置b相同,那么就还选上一个a(因为n可以小于m),所以可以多选。然后就可以利用快拍的思想来优化。因为是bi+1个数,所以可以把比a[bi+...
  • nucshiyilang
  • nucshiyilang
  • 2017-07-25 21:24
  • 750

hdu 1276 士兵队列训练问题(水题)

士兵队列训练问题 Problem Description 某部队进行新兵队列训练,将新兵从一
  • tju_peter
  • tju_peter
  • 2017-01-14 14:40
  • 138

【基础编程】hdu题目分类

hdu题目分类(转) http://apps.hi.baidu.com/share/detail/17053154 1001 整数求和 水题 1002 C语言实验题——两个数比较 水题 1003 1、2、3、4、5... 简单题 1004 渊子赛马 排序+贪心的方法归并 1005 Hero...
  • XGsilence
  • XGsilence
  • 2016-10-10 17:07
  • 767

HDU 4738 双连通模版题

题意:给定n个点,m条无向边 下面m行表示u , v ,边权值 求所有桥中最小的桥的权值,如不存在输出-1 若图一开始就不连通或最小权值为0则输出1 附赠一大波测试数据:   #include #include #include #include #incl...
  • qq574857122
  • qq574857122
  • 2013-09-15 17:42
  • 2351

hdu 5178 二分查找

原文链接 源代码1: #include #include #include using namespace std; int main() { long long int i,j,k,l,r,n,t,m,mid; long long int a[100005]; scanf(&qu...
  • u014265347
  • u014265347
  • 2015-05-09 23:37
  • 526

BFS广度优先搜索(2)--hdu1495(BFS变形题)

非常可乐 Limit:1000MS    Memory Limit:32768KB    64bit IO Format:%I64d & %I64u Description Input Ou...
  • Acmer_Sly
  • Acmer_Sly
  • 2016-09-11 22:52
  • 645

hdu5916 规律题

题目传送门: http://acm.hdu.edu.cn/showproblem.php?pid=5916 题意:给两个数n,k(1 为所有排列可能中的第k小个排列 思路:观察发现2*k小于等于n,如果把2*k和k放到最前面,剩余的按互质进行排列,正好满足要求(队友想出来...
  • Li_Yufeng
  • Li_Yufeng
  • 2016-10-05 15:04
  • 468

HDU--2567 寻梦【水题】

寻梦 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4980  ...
  • hpuhjh
  • hpuhjh
  • 2015-02-09 11:30
  • 471
    个人资料
    • 访问:212436次
    • 积分:5643
    • 等级:
    • 排名:第5408名
    • 原创:365篇
    • 转载:1篇
    • 译文:1篇
    • 评论:11条
    最新评论