题意:有n个仓库,m个管理员,每个管理员有一个能力值P,每个仓库只能由一个管理员看管,但是每个管理员可以看管k个仓库(但是这个仓库分配到的安全值只有p/k,k=0,1,...),雇用的管理员的工资即为他们的能力值p和,问,使每个仓库的安全值最高的前提下,使的工资总和最小。

析:首先使用二分安全值,然后使用DP来判断是不是能够达到这个安全值,这个DP就是一个01背包,dp[i] 表示看管 i 个仓库的最少费用多少,dp[j] = min{dp[j], d[j-x] + cost[i]}。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#include <list>
#include <assert.h>
#include <bitset>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a, b, sizeof a)
//#define sz size()
#define pu push_up
#define pd push_down
#define cl clear()
#define all 1,n,1
#define FOR(x,n) for(int i = (x); i < (n); ++i)
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("in.txt", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e17;
const double inf = 1e20;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1100 + 10;
const int maxm = 1e5 + 10;
const int mod = 50007;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c) {
return r > 0 && r <= n && c > 0 && c <= m;
} int a[maxn], b[maxn];
int dp[maxn];
int ans; bool judge(int mid, bool ok){
ms(dp, INF); dp[0] = 0;
for(int i = 0; i < m; ++i){
int x = a[i] / mid;
for(int j = 1050; j >= x; --j)
dp[j] = min(dp[j], dp[j - x] + a[i]);
}
int res = INF;
for(int i = n; i <= 1050; ++i)
res = min(res, dp[i]);
if(ok) ans = res;
return res != INF;
} int main(){
while(scanf("%d %d", &n, &m) == 2 && n+m){
int l = 1, r = 0;
for(int i = 0; i < m; ++i) scanf("%d", a + i), r = max(r, a[i]);
while(l <= r){
int m = l + r >> 1;
if(judge(m, false)) l = m + 1;
else r = m - 1;
}
if(l == 1){ printf("0 0\n"); continue; }
judge(l - 1, 1);
printf("%d %d\n", l - 1, ans);
}
return 0;
}

  

UVa 10163 Storage Keepers (二分 + DP)的更多相关文章

  1. UVA 10163 - Storage Keepers(dp)

    本文出自   http://blog.csdn.net/shuangde800 题目链接: 点击打开链接 题意 有n个仓库,让m个人来看管.一个仓库只能由一个人来看管,一个人可以看管多个仓库. 每个人 ...

  2. UVA 10163 Storage Keepers(两次DP)

    UVA 10163 Storage Keepers(两次DP) http://uva.onlinejudge.org/index.php? option=com_onlinejudge&Ite ...

  3. DP(两次) UVA 10163 Storage Keepers

    题目传送门 /* 题意:(我懒得写,照搬网上的)有n个仓库,m个人看管.一个仓库只能由一个人来看管,一个人可以看管多个仓库. 每个人有一个能力值pi,如果他看管k个仓库,那么所看管的每个仓库的安全值为 ...

  4. uva 10163 - Storage Keepers(01背包)

    题目链接:10163 - Storage Keepers 题目大意:给出m为仓库的数量, 给出n为有守夜人的数量, 然后给出n个数值,为对应守夜人应付的酬劳,每个守夜人的能力与他需要的酬劳是相等的,并 ...

  5. UVA 10163 Storage Keepers(dp + 背包)

    Problem C.Storage Keepers  Background Randy Company has N (1<=N<=100) storages. Company wants ...

  6. uva 10163 Storage Keepers

    题意: 有n个仓库,m个人,一个仓库只能由一个人托管,每个人可以托管多个仓库. 每个人有一个能力值a,如果说他托管了k个仓库,那么这些仓库的安全值都是a/k. 雇佣一个人的花费也是a. 如果一个仓库没 ...

  7. UVA 10163 十六 Storage Keepers

    十六 Storage Keepers Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit ...

  8. 二分+DP HDU 3433 A Task Process

    HDU 3433 A Task Process Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/ ...

  9. hdu 3433 A Task Process 二分+dp

    A Task Process Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

随机推荐

  1. 【php 之获得当前日期以及比较日期大小】

    首先看一个例子: $currentTime = date('Y-m-d H:i'); // 获得当前时间 $timer = $searchDated . ' ' . $results['ctrip'] ...

  2. echarts中间有字饼图Demo1

    echarts链接:http://gallery.echartsjs.com/editor.html?c=xHy2vIPzLQ 代码: option = { backgroundColor: 'bla ...

  3. C++ 读取文本文件内容到结构体数组中并排序

    成绩排行:从Score.txt文件读取学生信息,对其进行排序,按回答题数从大到小排,若相等,按分数从小到大排 #include<iostream> #include<fstream& ...

  4. springboot 日志2

      SpringBoot关于日志的官方文档 1.简述 SpringBoot官方文档关于日志的整体说明 本博客基于SpringBoot_1.3.6大家请先简单看下这篇英文的官方文档,文中有说 Sprin ...

  5. 史上最全的MSSQL复习笔记

    1.什么是SQL语句 SQL语言,结构化的查询语言(Structured Query Language),是关系数据库管理系统的标准语言.它是一种解释语言,写一句执行一句,不需要整体编译执行. 语法特 ...

  6. Oracle_SQL(1) 基本查询

    1.oracle的安装与卸载 2.PL/SQL Developer的安装 3.登陆PL/SQL Developer 4.SCOTT用户下表的介绍 5.基本查询语句 查询雇员的所有信息: select ...

  7. JavaScript获取DOM对象的几种方式

    1.getElementById() 方法可返回对拥有指定 ID 的第一个对象的引用 2.getElementsByName() 方法可返回带有指定名称的对象的集合 3.getElementsByTa ...

  8. (O)js核心:this

    什么是this this是js中的一个关键词,它总是指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境. 当函数被调用时,this被添加到作用域中,例如: ...

  9. python提取分析表格数据

    #/bin/python3.4# -*- coding: utf-8 -*- import xlrd def open_excel(file="file.xls"): try: d ...

  10. BZOJ1001或洛谷4001 [BJOI2006]狼抓兔子

    BZOJ原题链接 洛谷原题链接 显然就是求最小割. 而对于一个平面图有结论,最大流=最小割=对偶图最短路. 所以这题可用最大流或是转换为对偶图求最短路,这里我是用的对偶图. 虽然理论上按上界算,这题\ ...