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

  • 参考博客:
    http://blog.csdn.net/queuelovestack/article/details/52222085

  • 分析:给出N个工厂,每个工厂给出建造时间和费用,给出M个商店,每个商店给出收益和需要哪些工厂供货才能盈利,求获得L盈利的最小时间(盈利 = 商店的收益 - 工厂的投资费用)

  • 题解:
    要求最小时间,所以我们可以先二分搜索时间,因为时间是1~1000000000,所以二分搜并不会超时。每次搜到一个时间后判断这个时间下的最大盈利是否满足要求。

    判断方法:
    我们可以先计算出每一个商店能够盈利的最大时间,即需要的工厂种建造时间最长的那个,这样就可以判断当前时间下该商店能不能盈利;然后再用一个值存储当前已经建造好的工厂的费用。所以该商店的盈利 = 商店收益 - 需要建造工厂总费用 + 已经建好工厂总费用。 每次选择盈利最大的商店后再更新当前未选取商店的已经建好工厂费用。直到当前不能选为止,过程中的最大盈利若超过L则满足,否则不满足。

  • AC代码:

/*************************************************************************
> File Name: 1012.cpp
> Author: Akira
> Mail: qaq.febr2.qaq@gmail.com
> Created Time: 2016年08月16日 星期二 18时44分04秒
************************************************************************/#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <set>
#include <list>
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
#define MST(a,b) memset(a,b,sizeof(a))
#define CLR(a) MST(a,0)
#define Sqr(a) ((a)*(a))using namespace std;#define MaxN 100000
#define MaxM MaxN*10
#define INF 1000000007
#define bug cout<<88888888<<endl;int T;
int N,M;
int tar;struct plants
{int pay,t;//工厂建造的花费和时间
}P[233];struct shop
{int pro;        //商店的盈利int K;          //商店所需要的工厂int index[233]; //工厂下标int time;       //工厂建造的最大时间int cost;       //建造工厂的总花费int finish;     //当前已经建好的工厂的花费
}S[233];struct Edge
{int v,next;
}edge[66666];
int cont;
int head[233];void add(int u, int v)
{edge[cont].v = v;edge[cont].next = head[u];head[u] = cont++;
}void init()
{cont = 0;MST(head,-1);
}
int Svis[233];
int Pvis[233];int judge(int t)
{int Get = -INF;CLR(Svis);CLR(Pvis);for(int i=1;i<=M;i++)S[i].finish = 0;            //每个商店对应的已建工厂清0int Max;                        //记录某次选择商店中的最大盈利     int tmp = 0;                        //记录总盈利for(int i=1;i<=M;i++)           //一共M个商店{Max = -INF;int choose;for(int j=1;j<=M;j++)       //遍历每一个商店,选择盈利最大的商店{if(!Svis[j] && S[j].time<=t)                     //如果该商店未遍历,且其盈利的最大时间不超过当前t时间,则进行判断{if(Max<S[j].pro-S[j].cost+S[j].finish)          //如果当前的商店盈利大于之前的选择,则更新这次选定的商店{Max = S[j].pro-S[j].cost+S[j].finish;       //更新盈利   choose = j;                                 //更新商店下标}}}if(Max == -INF) break;      //说明没有商店可以选了,则跳出Svis[choose] = 1;           //标记选过的商店tmp+=Max;                   //更新总盈利Get = max(tmp, Get);        //更新过程中达到的最大盈利       for(int j=1;j<=S[choose].K;j++)                          //遍历当前选择商店需要的所有工厂{if(!Pvis[S[choose].index[j]])                       //找到没有建造的工厂{Pvis[S[choose].index[j]] = 1;                   //建造它for(int l = head[S[choose].index[j]]; l!=-1; l = edge[l].next) //然后通过邻接链表更新没选取的商店的已建造好工厂的费用{if(!Svis[edge[l].v])                        //找到未选取的商店S[edge[l].v].finish += P[S[choose].index[j]].pay;}}}}if(Get >= tar)return Get;return 0;
}int main()
{scanf("%d", &T);int tt = 1;while(T--){init();scanf("%d%d%d", &N, &M, &tar);for(int i=1;i<=N;i++){scanf("%d%d", &P[i].pay, &P[i].t);}for(int i=1;i<=M;i++){scanf("%d%d", &S[i].pro, &S[i].K);S[i].time = S[i].cost = 0;for(int j=1;j<=S[i].K;j++){scanf("%d", &S[i].index[j]);add(S[i].index[j], i);S[i].time = max(S[i].time, P[S[i].index[j]].t);S[i].cost += P[S[i].index[j]].pay;}}int l=1;int r=1000000000;int Min = INF;int mid;int ans;while(l<=r){mid = (l+r)/2;int tmp = judge(mid);if(tmp){ans = tmp;Min = min(mid, Min);r = mid-1;}elsel = mid+1;}if(Min != INF)printf("Case #%d: %d %d\n", tt++, Min, ans);elseprintf("Case #%d: impossible\n", tt++);}return 0;
}

二分+贪心——HDU 5855相关推荐

  1. 蒟蒻的第一篇博客CF1041C Coffee Break(二分+贪心+set)

    CF1041C Coffee Break(二分+贪心+set) 描述 Recently Monocarp got a job. His working day lasts exactly mm min ...

  2. 洛谷P1182 数列分段 Section II(二分+贪心)

    题目描述 对于给定的一个长度为N的正整数数列 A1∼NA _{1∼N}A1∼N​,现要将其分成 M(M≤N)M(M≤N)M(M≤N)段,并要求每段连续,且每段和的最大值最小. 关于最大值最小: 例如一 ...

  3. 树状数组 + 二分 - Query HDU - 4339

    树状数组 + 二分 - Query HDU - 4339 题意: T组测试用例,每组给定两个长度分别为l1和l2的字符串s1,s2.有两种询问:①.1idic:将第id个字符串的第i个字符变成字符c. ...

  4. Java编写胖老鼠的交易,猫鼠交易(贪心) HDU 1009 FatMouse' Trade

    猫鼠交易(贪心) HDU 1009 FatMouse' Trade FatMouse prepared M pounds of cat food, ready to trade with the ca ...

  5. hdu 5248(二分+贪心)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5248 解题思路:这道题我原本的思路是动态规划,结果看到数很大,结果放弃了.然后想到二分,思路是对的,只 ...

  6. [USACO16JAN]Angry Cows S[二分+贪心]

    题意:Bessie 设计了一款新游戏:Angry Cows.在这个游戏中,玩家发射奶牛,每头奶牛落地时引爆一定范围内的干草.游戏的目标是使用一组奶牛引爆所有干草. N 捆干草排列在数轴上的不同位置.第 ...

  7. BZOJ2525 [Poi2011]Dynamite 【二分 + 贪心】

    题目链接 BZOJ2525 题解 就是要求所有有炸弹的点到点燃点距离最大值最小 显然二分答案距离\(D\) 然后按深度排序,贪心点燃当前没覆盖的深度最深的点往上第\(D\)层的点 每覆盖一个点要标记其 ...

  8. hdu5248序列变换(二分+贪心)基础题

    题意(中文的直接粘题意吧)                                                                                        ...

  9. 外卖(food) 洛谷4040宅男计划 三分套二分贪心

    food评测传送门 [题目描述] 叫外卖是一个技术活,宅男宅女们一直面对着一个很大的矛盾,如何以有限的金钱在宿舍宅得尽量久.     外卖店一共有 N 种食物,每种食物有固定的价钱 Pi 与保质期 S ...

  10. LA 4254 Processor 处理器 【二分 贪心 优先队列】

    题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=21663 二分: 最大值最小的问题通过二分来求解.对处理器速度进行 ...

最新文章

  1. iOS-消除CocoaPods内容警告
  2. Asp.net中基于Forms验证的角色验证授权[转]
  3. 后台服务系统之什么是dubbo
  4. 阿里云数据中台助力零售耐消品新客获取与转化
  5. 【英语学习】【Level 08】U02 Movie Time L2 In black and white
  6. idea json转为对象_数据存储—JSON
  7. ASP.NET AJAX入门系列(5):使用UpdatePanel控件(二)
  8. PyQt5多线程刷新界面防假死
  9. Django3 快速入门
  10. 谷歌浏览器截取整个网页为图片(无需插件)
  11. adb 查看浏览器内核
  12. HCIP 数通资料下载 肖哥视频
  13. 四月,诗月,你是最美人间四月天。
  14. 基于Spark的电商用户行为分析系统的设计与实现
  15. App Thinning(应用瘦身)功能介绍
  16. 3大场景、4款新品公开亮相:「低速智能驾驶」新赛道惹关注
  17. sqlserver实现只查询一条数据
  18. 年前更新 阿里云冬季实战营第二期:Linux操作系统实战入
  19. MPEG4基础知识简介以及 判断MPEG4的I, P, B帧
  20. 停车收费PDA手持终端

热门文章

  1. Google SketchUp SKP文件转OBJ 专业版注册机
  2. html5游戏 搭积木,搭积木游戏
  3. 智能家居控制系统制作技术_智能家居控制系统是什么_智能家居控制系统的由来-装修攻略...
  4. Linux服务器重启导致数据丢失问题解决
  5. python简历模板_于是我用 Python 重写了那个上千 star 的“开源”简历模板
  6. vb服务器获取ftp文件,vb获取ftp服务器文件时间戳
  7. 如何设置正确的dns服务器地址,dns服务器地址如何设置
  8. 事件监听(窗口关闭、输入框事件、计算器、画笔、鼠标、窗口、键盘)
  9. 手机共享计算机网络连接,如何将手机wifi网络通过USB共享给电脑?教您共享方法...
  10. colorbox去除close关闭按钮,附上colorbox的基本使用方法