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函数可以用前缀和+二分查找优化,否则会超时

这题挂了好几次,

  1. 写了前缀和,后面忘记写二分查找
  2. 没有用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)的更多相关文章

  1. 没有找零 状压dp

    没有找零 状压dp 约翰到商场购物,他的钱包里有K(1 <= K <= 16)个硬币,面值的范围是1..100,000,000.约翰想按顺序买 N个物品(1 <= N <= 1 ...

  2. Codeforces 1383C - String Transformation 2(找性质+状压 dp)

    Codeforces 题面传送门 & 洛谷题面传送门 神奇的强迫症效应,一场只要 AC 了 A.B.D.E.F,就一定会把 C 补掉( 感觉这个 C 难度比 D 难度高啊-- 首先考虑对问题进 ...

  3. FZU 2093 找兔子 状压DP

    题目链接:找兔子 n的范围是[1, 15],可以用0 到 (1<<n)-1 的数表示全部状态,用dp[i] = t表示到达状态i的最少时间是t,对于每个点,如果它能到达的所有点在t秒时都已 ...

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

    传送门 先通过二分预处理出来,每个硬币在每个商品处最多能往后买多少个商品 直接状压DP即可 f[i]就为,所有比状态i少一个硬币j的状态所能达到的最远距离,在加上硬币j在当前位置所能达到的距离,所有的 ...

  5. 【BZOJ3312】[Usaco2013 Nov]No Change 状压DP+二分

    [BZOJ3312][Usaco2013 Nov]No Change Description Farmer John is at the market to purchase supplies for ...

  6. Codeforces 1225G - To Make 1(bitset+状压 dp+找性质)

    Codeforces 题目传送门 & 洛谷题目传送门 还是做题做太少了啊--碰到这种题一点感觉都没有-- 首先我们来证明一件事情,那就是存在一种合并方式 \(\Leftrightarrow\) ...

  7. ZOJ3802 Easy 2048 Again (状压DP)

    ZOJ Monthly, August 2014 E题 ZOJ月赛 2014年8月 E题 http://acm.zju.edu.cn/onlinejudge/showProblem.do?proble ...

  8. LGTB与序列 状压dp

    考试一看我就想到了状压dp.当时没有想到素数,以为每一位只有0~9这些数,就开始压了.后来发现是小于30,然后改到了15,发现数据一点不给面子,一个小点得数都没有,完美爆零.. 考虑到bi最多变成58 ...

  9. 树形DP和状压DP和背包DP

    树形DP和状压DP和背包DP 树形\(DP\)和状压\(DP\)虽然在\(NOIp\)中考的不多,但是仍然是一个比较常用的算法,因此学好这两个\(DP\)也是很重要的.而背包\(DP\)虽然以前考的次 ...

随机推荐

  1. ElasticSearch之QueryBuilders

    1.termsQuery A filer for a field based on several terms matching on any of them 翻译过来:基于以下几个方面对其中任何匹配 ...

  2. 大数据kafka视频教程 学习记录【B站尚硅谷 】

    视频地址: https://www.bilibili.com/video/av35354301/?p=1           2019/03/06 21:59 消息队列的内部实现: Kafka基础: ...

  3. spring boot整合redis,以及设置缓存过期时间

    spring-boot 整合 redis 注:redis服务器要先开启 pom文件: <dependency> <groupId>org.springframework.boo ...

  4. CF1182E Product Oriented Recurrence

    思路: fn = can * f1xn * f2yn * f3zn, 首先dp计算指数部分an = an-1 + an-2 + an-3 + 2 * n - 6, 而an-1 = an-2 + an- ...

  5. <script>, <script async>, <script defer> 三种标签的区别

    <script>, <script async>, <script defer> 三种标签的区别 <script>标签 阻塞html parsing 脚 ...

  6. FusionCharts使用教程:为JavaScript图表提供数据

    FusionCharts的JavaScript类提供了一系列的函数来提供图表数据. FusionCharts的JavaScript类支持XML或JSON格式的数据.这些数据可以是URL或字符串. 以X ...

  7. 将腾讯视频客户端缓冲的文件转换为一个MP4格式文件

    打开腾讯视频windows客户端,播放要下载的视频,逐步快进使其缓冲完毕: 按照下图所示,复制缓存路径: 在cmd.exe的界面中输入“cd C:\854456b6d5a187ff3c0f553918 ...

  8. CSS样式表优化

    前几天公司要模仿一家客户的网站模板来为另一客户新建一个模板,说白了就是换个数据源,然后样式表再小修小改一下就行了.但通过浏览器控制台下载素材时,发现这个网站开发的挺专业的,单就样式表而言,代码工整,注 ...

  9. java核心技术 要点笔记3

    1.类,超类和子类 2.Object:所有类的超类 3.泛型数组列表 4.对象包装器和自动装箱 5.参数数量可变的方法 6.枚举类 7.反射 8.继承设计的技巧

  10. linux 命令——ls

    一.  ls命令 ls 命令是linux下最常用的命令.ls命令就是list的缩写缺省下ls用来打印出当前目录的清单如果ls指定其他目录那么就会显示指定目录里的文 件及文件夹清单. 通过ls 命 ...