[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\)虽然以前考的次 ...
随机推荐
- sql 删除字段 出错
1. 删除字段: ALTER TABLE TALE_NAME DROP COLUMN nn; 2.报错: 消息 5074,级别 16,状态 1,第 1 行对象'DF__WorkOrder__I ...
- IO字节流。
字节输出流: java.io.OutputStream :抽象类,是表示输出字节流的所有类的父类. java.io.FileOutputStream extends OutputStream: 文件字 ...
- java 整型相除得到浮点型
public class TestFloatOrDouble { public static void main(String[] args) { Point num1 = new Point(84, ...
- 零基础逆向工程31_Win32_05_提取图标_修改标题
在程序中使用图标 1.加载图标 HICON hIcon; hIcon = LoadIcon (hAppInstance, MAKEINTRESOURCE (IDI_ICON)); hAppInstan ...
- 在window下, Java调用执行bat脚本
参考博客: https://www.cnblogs.com/jing1617/p/6430141.html 最近一段时间用到了Java去执行window下的bat脚本, 这里简单记录一下: 我这里是先 ...
- 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:0.概述
欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 序言 帖主和队友仿制了一个简单版的微信,其中,队友是用Unity3D做前段,帖主用Java的Mina.Hiberna ...
- 一、基于Qt的图像矩形区域改色
Qt环境下图像的打开和涂色 一.设计目标 能够在 Qt QtCreator 环境下打开常用图像格式文件,诸如 bmp.jpg.png 图像等,然后将他们转化为 Qt 中的 QImage 类,并进行矩形 ...
- python3.7 安装 xlrd 模块---Mac
要用Excel将数据和代码分离,需要import xlrd, 使用前需要先安装xlrd模块. 说明:通过在google中搜索“xlrd Mac”,下载xlrd.py模块(下载地址:http://mac ...
- Linux常用命令-1
内部命令:属于Shell解释器的一部分(已调入内存) 外部命令:独立于Shell解释器之外的程序文件(在磁盘上) 获得命令帮助 1)内部命令help 查看Bash内部命令的帮助信息 2)命令的“--h ...
- POJ-1274 The Perfect Stall---二分图模板
题目链接: https://vjudge.net/problem/POJ-1274 题目大意: 有n个奶牛和m个谷仓,现在每个奶牛有自己喜欢去的谷仓,并且它们只会去自己喜欢的谷仓吃东西,问最多有多少奶 ...