[BZOJ3312][USACO]不找零(状压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。
Solution
发现K范围小,考虑状压DP,设\(F[S]\)表示所以消费卡状态为S时可以到达最后面的奶牛编号,即前面的奶牛都付完,
在二进制下1表示用过了,0表示没有
那么\(F[S|2^{k-1}]=max\{Get(card(k),F[S]+1)\}\) ,
\(Get(s,pos)\) 表示可用金额为s, 从\(Cow_{pos}\) 可到达最远的奶牛坐标,
那么Get函数可以用前缀和+二分查找优化,否则会超时
这题挂了好几次,
- 写了前缀和,后面忘记写二分查找
- 没有用max!WA了,居然还过了好多点
Code
#include <cstdio>
#include <algorithm>
#define N 100010
using namespace std;
int n, k, card[19], sum[N], cow[N], f[1 << 19], Ans;
inline int read() {
int x = 0, f = 1; char ch = getchar();
while (ch < '0' || ch > '9') {if (ch == '-')f = -1; ch = getchar();}
while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
return x * f;
}
inline int get(int k, int st) {
int l = st, r = n, res;
while (l <= r) {
int mid = (l + r) >> 1;
if (sum[mid] - sum[st - 1] <= k)
res = mid, l = mid + 1;
else r = mid - 1;
}
return res;
}
inline int cnt(int S) {
int r = 0;
for (int i = 1; i <= k; ++i)
if (!(S & (1 << (i - 1))))
r += card[i];
return r;
}
int main() {
k = read(), n = read();
for (int i = 1; i <= k; ++i) card[i] = read();
for (int i = 1; i <= n; ++i) {
cow[i] = read();
sum[i] = sum[i - 1] + cow[i];
}
Ans = -1;
for (int S = 0; S < (1 << k); ++S) {
if (f[S] == n) continue;
for (int i = 1; i <= k; ++i) {
int T = (1 << (i - 1));
if (S & T) continue;
f[S | T] = max(f[S | T], get(card[i], f[S] + 1));
if (f[S | T] == n)
Ans = max(Ans, cnt(S | T));
}
}
printf("%d\n", Ans);
return 0;
}
[BZOJ3312][USACO]不找零(状压DP)的更多相关文章
- 没有找零 状压dp
没有找零 状压dp 约翰到商场购物,他的钱包里有K(1 <= K <= 16)个硬币,面值的范围是1..100,000,000.约翰想按顺序买 N个物品(1 <= N <= 1 ...
- Codeforces 1383C - String Transformation 2(找性质+状压 dp)
Codeforces 题面传送门 & 洛谷题面传送门 神奇的强迫症效应,一场只要 AC 了 A.B.D.E.F,就一定会把 C 补掉( 感觉这个 C 难度比 D 难度高啊-- 首先考虑对问题进 ...
- FZU 2093 找兔子 状压DP
题目链接:找兔子 n的范围是[1, 15],可以用0 到 (1<<n)-1 的数表示全部状态,用dp[i] = t表示到达状态i的最少时间是t,对于每个点,如果它能到达的所有点在t秒时都已 ...
- [luoguP3092] [USACO13NOV]没有找零No Change(状压DP + 二分)
传送门 先通过二分预处理出来,每个硬币在每个商品处最多能往后买多少个商品 直接状压DP即可 f[i]就为,所有比状态i少一个硬币j的状态所能达到的最远距离,在加上硬币j在当前位置所能达到的距离,所有的 ...
- 【BZOJ3312】[Usaco2013 Nov]No Change 状压DP+二分
[BZOJ3312][Usaco2013 Nov]No Change Description Farmer John is at the market to purchase supplies for ...
- Codeforces 1225G - To Make 1(bitset+状压 dp+找性质)
Codeforces 题目传送门 & 洛谷题目传送门 还是做题做太少了啊--碰到这种题一点感觉都没有-- 首先我们来证明一件事情,那就是存在一种合并方式 \(\Leftrightarrow\) ...
- ZOJ3802 Easy 2048 Again (状压DP)
ZOJ Monthly, August 2014 E题 ZOJ月赛 2014年8月 E题 http://acm.zju.edu.cn/onlinejudge/showProblem.do?proble ...
- LGTB与序列 状压dp
考试一看我就想到了状压dp.当时没有想到素数,以为每一位只有0~9这些数,就开始压了.后来发现是小于30,然后改到了15,发现数据一点不给面子,一个小点得数都没有,完美爆零.. 考虑到bi最多变成58 ...
- 树形DP和状压DP和背包DP
树形DP和状压DP和背包DP 树形\(DP\)和状压\(DP\)虽然在\(NOIp\)中考的不多,但是仍然是一个比较常用的算法,因此学好这两个\(DP\)也是很重要的.而背包\(DP\)虽然以前考的次 ...
随机推荐
- (转载)ASP.NET Quiz Answers: Does Page.Cache leak memory?
原文地址:http://blogs.msdn.com/b/tess/archive/2006/08/11/695268.aspx "We use Page.Cache to store te ...
- js 数组对象去重
let hash = {}; let config = [ { name: 2, state: true, output: 'Y'}, { name: 3, state: true, output: ...
- Counting blessings can actually increase happiness and health by reminding us of the good things in life.
Counting blessings can actually increase happiness and health by reminding us of the good things in ...
- Eucalyptus管理页面密码设置
桉树环境什么的都已经是配置好了的,但是过了一段时间不用,也不知道密码是什么了,看着下面的页面也不知道如何进去,这里我们通过命令行的方式重置用户名和密码信息. 登陆clc所在机器,输入下命令: euar ...
- ElasticSearch 5学习(5)——第一个例子
想要知道ElasticSearch是如何使用的,最快的方式就是通过一个简单的例子,第一个例子将会包括基本概念如索引.搜索.和聚合等,需求是关于公司管理员工的一些业务. 员工文档索引 业务首先需要存储员 ...
- World Wind Java开发之七——读取本地栅格文件(影像+高程)构建三维场景(转)
http://blog.csdn.net/giser_whu/article/details/41679515 首先,看下本篇博客要达到的效果图: 下面逐步分析如何加载影像及高程文件. 1.World ...
- Android(java)学习笔记87:Android音视频MediaRecorder用法
1. Android语音录制可以通过 MediaRecorder 和 AudioRecorder: MediaRecorder本来是多媒体录制控件,可以同时录制视频和语音,当不指定视频源时就只录制语 ...
- Linux运维工程师是什么鬼?
第一部分:定义 运维工程师,字面理解运行维护. linux运维即linux运维工程师,集合网络.系统.数据库.开发.安全工作于一身的“复合性人才”. 除了传统IT运维部分,运维人员还是管理制度.规 ...
- URL Schemes 不能识别和不能跳转的原因
在app跳转的过程中 需要设置url schemes后,但是设置完后,却不能识别, (测试方式:URL scheme + ://)在浏览器中打开,如果能打开app,就是能跳转 今天遇到了一个坑爹的问题 ...
- preprocessing MinMaxScaler
import numpy as npfrom sklearn.preprocessing import MinMaxScalerdataset = np.array([1,2,3,5]).astype ...