poj3190 poj2393 贪心

题目链接点击打开链接

题意: 有N头牛要求在时间段[A ,B](包括端点)内独享一个牛栏,请问至少需要多少个牛栏。

思路:先对所有奶牛按照起始时间A从大到小排序,对第i头牛来说,如果i.A 大于(不能等于)前面已经安排的牛栏的最早结束时间(设该牛栏为M),则将牛栏M分配给牛i ,并更新M的结束时间 , M= i.B ;否则新增一个牛栏,并把它分配给牛i。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <math.h>
#include <string.h>
#include <queue>
using namespace std;
const int maxn = 50006 ;
struct cows
{
    int begin , end ;
    int index ;
}C[maxn];


struct stall
{
    int id ;
    int end ;
    bool operator < (const stall &b) const
    {
        return end > b.end ;
    }
} ;

bool cmp(cows A , cows B)
{
    if(A.begin == B.begin)
        return A.end < B.end ;
    else return A.begin < B.begin ;
}

priority_queue <stall> que ; //小顶堆
int result[maxn] ;

void put_cow(const int& i , const bool & new_stall)
{
    stall s ;
    if(new_stall)
    {
        s.id = que.size() + 1 ;
    }
    else
    {
        s.id = que.top().id ; que.pop() ;
    }
    s.end = C[i].end ;
    result[C[i].index] = s.id ; //因为C排过序,所以用索引记录原来标号
    que.push(s) ;
}

int main()
{
    //freopen("a.txt" , "r" , stdin) ;
    int n ;
    while(scanf("%d" , &n) !=EOF)
    {
        while(!que.empty())
        {
            que.pop() ;
        }
        for(int i = 0 ; i < n ; i ++)
        {
            C[i].index = i ;
            scanf("%d%d" , &C[i].begin , &C[i].end) ;
        }

        sort(C , C+n , cmp) ;
        put_cow(0, true) ;
      //  C[0].stallId = 1 ;
        for(int i = 1 ; i < n ; i ++)
        {
            put_cow(i , C[i].begin <= que.top().end) ; //易错,注意=号
        }
        printf("%d\n" , que.size()) ;
        for(int i = 0 ; i < n ; i ++)
            printf("%d\n" , result[i]) ;
    }
    return 0 ;
}



poj 2393

题目链接点击打开链接

题意:有一个工厂,第i周生产单位奶酪的成本为cost_i , 第i周奶酪的需求量为need_i , 工厂有储存室,每周存放单位奶酪的成本为S , 工厂的生产力和储存室储存量都可无限大,求N周 工厂的合计成本至少为多少。

思路:比较当前第i周的单位生产成本是否小于前i-1周中最小的生产成本+存放成本 , 若小于则用前i-1周中最小的生产成本+存放成本当作成本生产 ,否则用本周的生产成本。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <string.h>
#include <queue>
using namespace std;
const int maxn = 10005;
int n , s ;
long long sum ;
struct week
{
    int cost , need ;
    int index ;
    bool operator < (const week &w) const
    {
        return cost + (w.index - index)*s > w.cost ;
    }
}W[maxn];

priority_queue <week> que ; // 小顶堆

void add_product(const int &i , const bool &new_product)
{
    week C , A;

    if(new_product)
    {
        C.cost = W[i].cost ;
        C.need = W[i].need ;
        C.index = W[i].index ;
        que.push(C) ;
    }
    else
    {
        C.cost = (W[i].index - que.top().index)*s + que.top().cost ;
        C.need = W[i].need ;
    }
   // printf("%d %d\n" , que.top().cost , que.top().index) ;
    sum += C.cost * C.need ;
    //printf("cost=%d need=%d sum=%d\n" , C.cost , C.need , sum) ;
}

int main()
{
    //freopen("a.txt" , "r" , stdin) ;
    while(scanf("%d%d" , &n , &s) != EOF)
    {
        while(!que.empty())
        {
            que.pop() ;
        }
        for(int i = 1 ; i <= n ; i ++)
        {
            scanf("%d%d" , &W[i].cost , &W[i].need) ;
            W[i].index = i ;
        }
        sum = 0 ;
        add_product(1 , true) ;
        for(int i = 2 ; i <= n ; i ++)
        {
            add_product(i , W[i].cost <= (W[i].index-que.top().index)*s + que.top().cost) ;
        }
        printf("%I64d\n" , sum) ;
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值