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的更多相关文章
- poj 3040 Allowance
Allowance Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1842 Accepted: 763 Descript ...
- bzoj:1685 [Usaco2005 Oct]Allowance 津贴
Description As a reward for record milk production, Farmer John has decided to start paying Bessie t ...
- P2376 [USACO09OCT]津贴Allowance
P2376 [USACO09OCT]津贴Allowance一开始想的是多重背包,但是实践不了.实际是贪心,让多c尽可能少,所以先放大的,最后让小的来弥补. #include<iostream&g ...
- 洛谷 P2376 [USACO09OCT]津贴Allowance 解题报告
P2376 [USACO09OCT]津贴Allowance 题目描述 作为创造产奶纪录的回报,\(Farmer\) \(John\)决定开始每个星期给\(Bessie\)一点零花钱. \(FJ\)有一 ...
- 【BZOJ】1685: [Usaco2005 Oct]Allowance 津贴(贪心)
http://www.lydsy.com/JudgeOnline/problem.php?id=1685 由于每个小的都能整除大的,那么我们在取完大的以后(不超过c)后,再取一个最小的数来补充,可以证 ...
- 【POJ - 3040】Allowance(贪心)
Allowance 原文是English,这里就放Chinese了 Descriptions: 作为创纪录的牛奶生产的奖励,农场主约翰决定开始给Bessie奶牛一个小的每周津贴.FJ有一套硬币N种(1 ...
- Greedy:Allowance(POJ 3040)
零用钱大作战 题目大意:农夫和牛又搞新花样了,现在农夫想给Bessie每个星期都给一点零用钱,农夫有一堆面值的钱币,并且这个钱币都能被上一个钱币整除(1,5,10,50),并且钱币有一定数量,要你求最 ...
- poj-3040 Allowance (贪心)
http://poj.org/problem?id=3040 FJ 有n种不同面值的硬币,每种硬币都有相应的个数,大面值的硬币值总能被小面值的硬币值整除,每周需要支付 Bessie c元,问最多能 ...
- POJ 3040 Allowance 贪心
这题目的贪心思路还是有一点细节问题的. 还没有证明,据说是因为题目给的条件是每个价格是比它小的价格的倍数才能这么贪心的. 思路如下: 假设要给奶牛的钱为C 1)从大面值到小面值一次拿钱,能拿多少拿多少 ...
随机推荐
- Codeforces 353E 贪心
题意:给你一张有向图,第i条边连接i号点和(i + 1) % n号点,问最多可以选择多少个点,使得这些点互相不可达. 思路:容易发现,如果某个边的集合点的数目大于等于2,那么就可以选出一个点,当然也可 ...
- IO复用: select 和poll 到epoll
linux 提供了select.poll和epoll三种接口来实现多路IO复用.下面总结下这三种接口. select 该函数允许进程指示内核等待多个事件中的任何一个发生,并只在有一个或多个事件发生或经 ...
- 树形查询sql
DROP FUNCTION IF EXISTS PersonName; CREATE FUNCTION PersonName(parent_id smallint) RETURNS VARCHAR(2 ...
- ios微信分享的兼容性问题
我微信分享采用的是: 页面初始化时动态加载js-sdk, 然后在需要分享的页面进行sdk的分享初始化 app.vue store.vue 这种方法在安卓上完全正常, 好用得令人发指, 但是!!! io ...
- 管理Session
1:把session和本地线程绑定在一起. 1):创建一个sessionFactory.然后由它去创建session package com.hq.util; import org.hibernate ...
- SpringBoot使用Swagger2搭建强大的RESTful API 文档功能
swagger用于定义API文档. Swagger2的使用 Maven Plugin添加Swagger2相关jar包 <!--swagger2 start--> <dependenc ...
- OC学习篇之---Foundation框架中的NSDirctionary类以及NSMutableDirctionary类
昨天学习了Foundation框架中NSArray类和NSMutableArray类:http://blog.csdn.net/jiangwei0910410003/article/details/4 ...
- java并发编程笔记(二)——并发工具
java并发编程笔记(二)--并发工具 工具: Postman:http请求模拟工具 Apache Bench(AB):Apache附带的工具,测试网站性能 JMeter:Apache组织开发的压力测 ...
- 监听器、拦截器完成对session、cookie的会话控制
package com.trsmedia.interceptor; import java.util.Date; import java.util.Timer; import java.util.Ti ...
- 用 Flask 来写个轻博客 (4) — (M)VC_创建数据模型和表
目录 目录 前文列表 扩展阅读 定义数据模型 models 创建表 前文列表 用 Flask 来写个轻博客 (1) - 创建项目 用 Flask 来写个轻博客 (2) - Hello World! 用 ...