Allowance

有n种数字,第i种数字值为\(v_i\),有\(b_i\)个,保证随i的增大而增大,且对于任意i有\(a_{i-1}|a_i\)(显然,\(i\in(1,n]\)),现求将它们划分成最多的组数,并且保证每一组的数字的和大于等于c;\(n\leq 20,c,v\leq 10^8\)。

显然要分的组数最多,要能够做到拿出一组中的一个最小的数字,让其不满足条件,即填到尽量满,显然每一组都要尽可能做到。

于是我们从大往小填一组,如果当前枚举的数字为i,如果不选i,而转而选比i小的数字,容易发现因为整除的性质,那些比i小的数字必然会凑成i,更进一步,也就是选i的决策包含了不选i的决策,于是i一定要选。

因此我们就得到了一个凑的满满的组,显然再向其中填入一个数字,一定会超过c,容易知道,要让组数最大,显然需要填入一个当前能填的最小数字,这样满足了一组的和尽可能小,所以最优。

于是我们得到一个做法,从大到小枚举数字,填到不能填为止(这里应该用同余的知识优化,而不是一个一个选),再从小到大选择一个数字,如果总和大于等于c,则++ans。

考虑进一步优化,我们显然一个做法下来,得到了一个组的分配方法,于是我们可以copy,这样就可以做到很快了。

参考代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define il inline
#define ri register
#define Size 25
#define intmax 0x7fffffff
using namespace std;
struct coin{
int v,b;
il bool operator<(const coin&a)const{
return v<a.v;
}
}co[Size];
int ct,a[Size];
int main(){
int n,c,ans(0);
scanf("%d%d",&n,&c);
for(int i(1),v,b;i<=n;++i){
scanf("%d%d",&v,&b);
if(v>=c)ans+=b;
else co[++ct]={v,b};
}sort(co+1,co+ct+1);
while(true){int X(c);
for(int i(ct),j;i;--i){
j=min(X/co[i].v,co[i].b);
a[i]=j,X-=j*co[i].v,co[i].b-=j;
}
if(X)for(int i(1);i<=ct;++i)
if(co[i].b){++a[i],--co[i].b,X-=co[i].v;break;}
if(X>0)break;++ans;int opt(intmax);
for(int i(1);i<=ct;++i)
if(a[i])opt=min(opt,co[i].b/a[i]);ans+=opt;
for(int i(1);i<=ct;++i)co[i].b-=opt*a[i];
}printf("%d",ans);
return 0;
}

Allowance的更多相关文章

  1. poj 3040 Allowance

    Allowance Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1842   Accepted: 763 Descript ...

  2. bzoj:1685 [Usaco2005 Oct]Allowance 津贴

    Description As a reward for record milk production, Farmer John has decided to start paying Bessie t ...

  3. P2376 [USACO09OCT]津贴Allowance

    P2376 [USACO09OCT]津贴Allowance一开始想的是多重背包,但是实践不了.实际是贪心,让多c尽可能少,所以先放大的,最后让小的来弥补. #include<iostream&g ...

  4. 洛谷 P2376 [USACO09OCT]津贴Allowance 解题报告

    P2376 [USACO09OCT]津贴Allowance 题目描述 作为创造产奶纪录的回报,\(Farmer\) \(John\)决定开始每个星期给\(Bessie\)一点零花钱. \(FJ\)有一 ...

  5. 【BZOJ】1685: [Usaco2005 Oct]Allowance 津贴(贪心)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1685 由于每个小的都能整除大的,那么我们在取完大的以后(不超过c)后,再取一个最小的数来补充,可以证 ...

  6. 【POJ - 3040】Allowance(贪心)

    Allowance 原文是English,这里就放Chinese了 Descriptions: 作为创纪录的牛奶生产的奖励,农场主约翰决定开始给Bessie奶牛一个小的每周津贴.FJ有一套硬币N种(1 ...

  7. Greedy:Allowance(POJ 3040)

    零用钱大作战 题目大意:农夫和牛又搞新花样了,现在农夫想给Bessie每个星期都给一点零用钱,农夫有一堆面值的钱币,并且这个钱币都能被上一个钱币整除(1,5,10,50),并且钱币有一定数量,要你求最 ...

  8. poj-3040 Allowance (贪心)

    http://poj.org/problem?id=3040 FJ 有n种不同面值的硬币,每种硬币都有相应的个数,大面值的硬币值总能被小面值的硬币值整除,每周需要支付 Bessie   c元,问最多能 ...

  9. POJ 3040 Allowance 贪心

    这题目的贪心思路还是有一点细节问题的. 还没有证明,据说是因为题目给的条件是每个价格是比它小的价格的倍数才能这么贪心的. 思路如下: 假设要给奶牛的钱为C 1)从大面值到小面值一次拿钱,能拿多少拿多少 ...

随机推荐

  1. 六、Redis五种类型 - hash(散列)类型

    1.介绍 (1).hash也是一种字典结构,存储了字段(field)和字段值(value)的映射,字段值只能是字符串,不支持其他类型.(2).适合存储对象,对象列表和ID构成键名,字段表示对象的属性, ...

  2. oracle trim无效?

    这里说说如果是全角空格怎么去除 方法一 trim(TO_SINGLE_BYTE('aaa')) 方法二 SELECT TRIM(replace('aaa',' ','')) FROM dual

  3. Java中的多表&事务&DCL&一个多表操作例子

    准备sql: 创建部门表 CREATE TABLE dept( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(20) ); INSERT INTO d ...

  4. shell变量,字符串,数组

    一.shell变量定义: 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头: 中间不能有空格,可以使用下划线: 不能使用标点符号: 不能使用bash里的关键字. 变量使用: 使用一个定义过的 ...

  5. 数据中台核心方法论--OneModel为何需要产品化支撑?

    什么是产品化 大部分创业公司都是从一个伟大的想法创意开始的,并且需要有一堆技术专家来实现.我们清楚,伟大的技术并不等同于和伟大的产品,技术可以解决问题,但如果它没有办法法规模化,那这些技术或者能力对用 ...

  6. PHP FILTER_CALLBACK 过滤器

    定义和用法 FILTER_CALLBACK 过滤器调用用户自定义函数来过滤数据. 该过滤器为我们提供了对数据过滤的完全控制. 指定的函数必须存入名为 "options" 的关联数组 ...

  7. hdu 4352 XHXJ's LIS (数位dp+状态压缩)

    Description #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then carefully readin ...

  8. JDK 9 发布仅数月,为何在生产环境中却频遭嫌弃?

    千呼万唤始出来,在经历了整整一年的跳票之后,Java 9 终于在 9 月 21 日拨开云雾,露出真正的面目.对众多 Java 程序员来说,这一天无疑是一个重大的日子,首先 Java 开发者们再也不用羡 ...

  9. H5+SDK

    1.(个人猜测): SDK是写在容器(手机操作系统上的webview组件)上的应用,对H5应用暴露规定的API接口.相当于浏览器的开发者,给浏览器中新增了某些方法,js直接通过接口就可以调用的. 这个 ...

  10. linux之-mysql数据库2

    1.新建数据库 语句格式为 CREATE DATABASE <数据库名字>;,(注意不要漏掉分号 ;),前面的 CREATE DATABASE 也可以使用小写,具体命令为: 2.连接数据库 ...