zoukankan      html  css  js  c++  java
  • zjnu1189 土地租用(完整版)

    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 77   Accepted: 10

    Description

    随着YYHS的OI集训队人数急剧增加,原有的小机房已经容纳不了数量庞大的队员。
    于是史老师决定租用一些实验室机位供队员们训练,他正在考虑为N (1 <= N <= 50,000)位队员租用机位。实验室管理员根据要求给出了N个机位的长和宽,每个机位的长宽满足(1 <= 宽 <= 1,000,000; 1 <= 长 <= 1,000,000).
    而机位的租用价格是它的面积,实验室管理员也提出,可以同时租用多个机位. 租用这一组机位的价格是它们最大的长乘以它们最大的宽, 但是机位的长宽不能交换. 如果想租下一个3x5的机位和一个5x3的机位,则他需要付5x5=25.
    于是问题出现了,史老师希望租下所有的机位,但是他发现分组来租这些机位可以节省经费. 他需要你帮助他找到最小的经费.
     

    Input

    * 第1行: 一个数: N
    * 第2..N+1行: 每行包含两个数,分别为机位的长和宽
     

    Output

    * 第一行: 最小的可行费用.

    Sample Input

    4 100 1 15 15 20 5 1 100

    Sample Output

    500

    这题如果是用n*n的dp,会超时,所以要用斜率优化,和hdu3669差不多的思路。

    #include<iostream>
    #include<math.h>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<string>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define inf 999999999999999999
    #define maxn 50050
    struct node{
        ll w,h;
    }a[maxn],b[maxn];
    
    bool cmp(node a,node b){
        if(a.w==b.w)return a.h>b.h;
        return a.w>b.w;
    }
    ll dp[maxn];
    ll q[1111111];
    ll getup(int x)
    {
        return dp[x];
    }
    ll getdown(int x)
    {
        return -b[x+1].w;
    
    }
    
    
    int main()
    {
        int n,m,i,j,tot,k;
        while(scanf("%d",&n)!=EOF)
        {
            for(i=1;i<=n;i++){
                scanf("%d%d",&a[i].w,&a[i].h);
            }
            sort(a+1,a+1+n,cmp);
            tot=1;b[tot].w=a[1].w;b[tot].h=a[1].h;
            for(i=2;i<=n;i++){
                if(b[tot].h>=a[i].h)continue;
                tot++;b[tot].w=a[i].w;b[tot].h=a[i].h;
    
            }
            int front,rear;
            front=1;rear=1;
            q[rear]=0;
            for(i=1;i<=tot;i++){
                //dp[i]=b[1].w*b[i].h;  这里如果前面不把0加入队列的话,那么这句话要加上。
                while(front<rear && getup(q[front+1])-getup(q[front])<=b[i].h*(getdown(q[front+1])-getdown(q[front]) )  ){
                    front++;
                }
                k=q[front];
                dp[i]=dp[k]+b[k+1].w*b[i].h;
                //dp[i]=min(dp[i],dp[k]+b[k+1].w*b[i].h);
                while(front<rear && ( getup(q[rear])-getup(q[rear-1] ) )*(getdown(i)-getdown(q[rear] ))>=( getup(i)-getup(q[rear] ) )*(getdown(q[rear])-getdown(q[rear-1] ))   ){
                    rear--;
                }
                rear++;
                q[rear]=i;
    
            }
            printf("%lld
    ",dp[tot]);
        }
        return 0;
    }


  • 相关阅读:
    计算机的运算方法
    干货 Elasticsearch 知识点整理 一
    深入理解 Spring finishBeanFactoryInitialization
    Git 学习笔记
    深入理解 Mybatis
    深入理解 MyBatis 启动流程
    MyBatis 开发手册
    深入理解SpringMvc 启动流程
    深度长文回顾web基础组件
    快速排序
  • 原文地址:https://www.cnblogs.com/herumw/p/9464579.html
Copyright © 2011-2022 走看看