usaco No Change, 2013 Nov 不找零(二分查找+状压dp)

Description

约翰带着 N 头奶牛在超市买东西,现在他们正在排队付钱,排在第 i 个位置的奶牛需要支付 Ci 元。今天说好所有东西都是约翰请客的,但直到付账的时候,约翰才意识到自己没带钱,身上只有 K 张消费卡,第 i 张卡里有 Vi 元余额。

问题是,这些消费卡都是一次性的,它们可以被收银机读取,但如果卡一旦离开了收银机,卡里 的余额就会归零,而且超市也不负责找零!奶牛的队伍很长,不可能再调整她们的位置了,所以一张 卡只能支付一段连在一起的账单。而且,一张账单只能用一张消费卡支付,超市的系统不接受用两张 或以上的卡支付一笔账单。

约翰的问题就是按照什么样的顺序来使用这些消费卡,才能让他能为所有的奶牛买单,而且使得 剩余的消费卡的余额之和最大呢?

Input Format

? 第一行:两个整数 K 和 N ,1 ≤ K ≤ 16, 1 ≤ N ≤ 10^5

? 第二行到第 K + 1 行:第 i + 1 行有一个整数 Vi,1 ≤ Vi ≤ 10^9

? 第 K + 2 行到第 K + N + 1 行:第 i + K + 1 行有一个整数 Ci,1 ≤ Ci ≤ 10^4

Output Format

单个整数:表示约翰买完所有奶牛的单之后,最多还能剩多少余额,如果他带的卡根本没有办 法支付所有的账单,输出 ?1。

Sample Input

3 6
12
15
10
6
3
3
2
3
7

Sample Output

12
解释
用 10 元的卡支付前两笔账单,然后用 15 元
的卡支付后面所有的账单,还剩下一张 12 元的卡
没用

Hint

Source

No Change, 2013 Nov我们要维护两个值;f[i]是到i这个消费卡的使用状态最多能付多少奶牛的账单;g[i]是在f[i]最大前提下剩余的最多余额;由于在转移过程中要快速查找当前消费卡从当前位置开始能支付的最长序列;所以加上二分查找 T((1<<k)logn)设c为当前消费卡从当前位置开始能支付的最长序列的终点;那么就有以下方程

  if(c>f[i]||(c==f[i]&g[i-(1<<j-1)]-w[j]>g[i]))
  f[i]=c,g[i]=g[i-(1<<j-1)]-w[j];

 

#include<cstdio>
#include<iostream>
using namespace std;
int a[100010],g[1<<16],f[1<<16],w[20],ans=-1;
int i,j,n,k,inf,l,r,mid;
int find(int st,int x)
{
	l=st;r=n+1;a[n+1]=1e9;
	int ans;
	while(l+1<r)
	{
		mid=(l+r)>>1;
		if(a[mid]-a[st]>x)r=mid;
		else l=mid;
	}
	return l;
}
int main()
{
//	freopen("xx.in","r",stdin);
	scanf("%d%d",&k,&n);
	for(i=1;i<=k;g[0]+=w[i],++i)
	scanf("%d",&w[i]);
	for(i=1;i<=n;a[i]+=a[i-1],++i)
	scanf("%d",&a[i]);
	inf=(1<<16)-1;
	for(i=1;i<=inf;++i)
	{
		for(j=1;j<=16;++j)
		if(i&1<<j-1)
		{
			int c=find(f[i-(1<<j-1)],w[j]);
			if(c>f[i]||(c==f[i]&g[i-(1<<j-1)]-w[j]>g[i]))
			f[i]=c,g[i]=g[i-(1<<j-1)]-w[j];
			if(f[i]==n&g[i]>ans)
			ans=g[i];
		}
	}
	printf("%d",ans);
}

  

时间: 2024-12-28 01:34:11

usaco No Change, 2013 Nov 不找零(二分查找+状压dp)的相关文章

【BZOJ1725】[Usaco2006 Nov]Corn Fields牧场的安排 状压DP

[BZOJ1725][Usaco2006 Nov]Corn Fields牧场的安排 Description Farmer John新买了一块长方形的牧场,这块牧场被划分成M列N行(1<=M<=12; 1<=N<=12),每一格都是一块正方形的土地.FJ打算在牧场上的某几格土地里种上美味的草,供他的奶牛们享用.遗憾的是,有些土地相当的贫瘠,不能用来放牧.并且,奶牛们喜欢独占一块草地的感觉,于是FJ不会选择两块相邻的土地,也就是说,没有哪两块草地有公共边.当然,FJ还没有决定在哪些土地

bzoj1725 [Usaco2006 Nov]Corn Fields牧场的安排(状压dp)

1725: [Usaco2006 Nov]Corn Fields牧场的安排 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 714  Solved: 502[Submit][Status][Discuss] Description Farmer John新买了一块长方形的牧场,这块牧场被划分成M列N行(1<=M<=12; 1<=N<=12),每一格都是一块正方形的土地.FJ打算在牧场上的某几格土地里种上美味的草,供他的奶牛们享用.遗憾的是

[Usaco2008 Nov]mixup2 混乱的奶牛 简单状压DP

1231: [Usaco2008 Nov]mixup2 混乱的奶牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 685  Solved: 383[Submit][Status][Discuss] Description 混乱的奶牛 [Don Piele, 2007] Farmer John的N(4 <= N <= 16)头奶牛中的每一头都有一个唯一的编号S_i (1 <= S_i <= 25,000). 奶牛为她们的编号感到骄傲,

bzoj1231[Usaco2008 Nov]mixup2 混乱的奶牛(状压dp)

1231: [Usaco2008 Nov]mixup2 混乱的奶牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1032  Solved: 588[Submit][Status][Discuss] Description 混乱的奶牛 [Don Piele, 2007] Farmer John的N(4 <= N <= 16)头奶牛中的每一头都有一个唯一的编号S_i (1 <= S_i <= 25,000). 奶牛为她们的编号感到骄傲

状压DP [Usaco2008 Nov]mixup2 混乱的奶牛

本人水平有限,题解不到为处,请多多谅解 本蒟蒻谢谢大家观看 题目: Problem H: [Usaco2008 Nov]mixup2 混乱的奶牛 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 109  Solved: 59[Submit][Status][Web Board] Description 混乱的奶牛 [Don Piele, 2007] Farmer John的N(4 <= N <= 16)头奶牛中的每一头都有一个唯一的编号S_i (1

硬币找零-记忆化搜索(DP动态规划)

硬币找零 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 在现实生活中,我们经常遇到硬币找零的问题,例如,在发工资时,财务人员就需要计算最少的找零硬币数,以便他们能从银行拿回最少的硬币数,并保证能用这些硬币发工资. 我们应该注意到,人民币的硬币系统是 100,50,20,10,5,2,1,0.5,0.2,0.1,0.05, 0.02,0.01 元,采用这些硬币我们可以对任何一个工资数用贪心算法求出其最少硬币数. 但不幸的是: 我们可能没有这样一种好的硬币系统, 因此

【状压dp】Bzoj1231 [Usaco2008 Nov]mixup2 混乱的奶牛

Description 混乱的奶牛 [Don Piele, 2007] Farmer John的N(4 <= N <= 16)头奶牛中的每一头都有一个唯一的编号S_i (1 <= S_i <= 25,000). 奶牛为她们的编号感到骄傲, 所以每一头奶牛都把她的编号刻在一个金牌上, 并且把金牌挂在她们宽大的脖子上. 奶牛们对在挤奶的时候被排成一支"混乱"的队伍非常反感. 如果一个队伍里任意两头相邻的奶牛的编号相差超过K (1 <= K <= 3400

[luoguP3092] [USACO13NOV]没有找零No Change(状压DP + 二分)

传送门 先通过二分预处理出来,每个硬币在每个商品处最多能往后买多少个商品 直接状压DP即可 f[i]就为,所有比状态i少一个硬币j的状态所能达到的最远距离,在加上硬币j在当前位置所能达到的距离,所有的取max 是满足最优解性质的 #include <cstdio> #include <iostream> #include <algorithm> #define N 17 #define max(x, y) ((x) > (y) ? (x) : (y)) int n

【USACO 2008 Nov Gold】 1.Mixed Up Cows 状压DP、

题解: 首先考虑dfs,但是看到答案的"64bit"就放弃了吧. 所以肯定是组合数.状压DP什么的,尤其是那个16,标准的状压数. 好吧,就是状压DP. f[i][j]表示i是状压的01串表示哪个取了哪个没取,然后j是结尾字符, 虽然水,但是时间复杂度是可以过的. 代码: #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include &