没有找零 状压dp

约翰到商场购物,他的钱包里有K(1 <= K <= 16)个硬币,面值的范围是1..100,000,000。约翰想按顺序买 N个物品(1 <= N <= 100,000),第i个物品需要花费c(i)块钱,(1 <= c(i) <= 10,000)。在依次进行的购买N个物品的过程中,约翰可以随时停下来付款,每次付款只用一个硬币,支付购买的内容是从上一次支付后开始到现在的这些所有物品(前提是该硬币足以支付这些物品的费用)。不幸的是,商场的收银机坏了,如果约翰支付的硬币面值大于所需的费用,他不会得到任何找零。请计算出在购买完N个物品后,约翰最多剩下多少钱。如果无法完成购买,输出-1。

如果我们枚举k的全排列是肯定超时的。显然对于一种硬币的选择方案,尽可能选更多的物品更优,没有必要枚举全排列。所以\(f[i]\)表示当前选硬币的状态为\(i\),在第i个物品处,用第j个硬币能到达的最远处。那么转移方程为\(f[i]=f[j]+a[f[j]][k]\),k可以通过i,j判断出来。别忘记要预处理a。那么时间复杂度则为\(O(knlog_2n+2^kn)\)。

感觉状压dp就是在dp减少无用状态的前提下贪心而已。

#include <cstdio>
#include <algorithm>
using namespace std; const int maxn=1e5+5, maxk=20;
int k, n, coins[maxn], things[maxn], pre[maxn];
// pre:物品的前缀和
int a[maxn][maxk]; //在第i个位置,用第j个硬币的能到达的地方。
int f[int(1e6)]; //一个状态最远能到达的地方 int calc(int now){
int re=0;
for (int i=k; i>0; --i){
re+=(1-(now&1))*coins[i];
now>>=1;
}
return re;
} int main(){
scanf("%d%d", &k, &n);
for (int i=1; i<=k; ++i) scanf("%d", &coins[i]);
for (int i=1; i<=n; ++i){
scanf("%d", &things[i]);
pre[i]=pre[i-1]+things[i];
}
int t, t2;
for (int i=1; i<=n; ++i)
for (int j=1; j<=k; ++j){
t=pre[i-1]+coins[j];
a[i][j]=upper_bound(pre+i, pre+n+1, t)-pre-i;
}
for (int i=0; i<(1<<k); ++i){
t=1;
for (int j=k; j>=1; --j){ //枚举前一个状态
if (t&i){
t2=i-t;
f[i]=max(f[i], f[t2]+a[f[t2]+1][j]);
}
t<<=1;
}
}
int ans=0; bool flag=false;
for (int i=0; i<(1<<k); ++i){
if (f[i]==n&&calc(i)>ans) ans=calc(i);
if (f[i]==n) flag=true;
}
printf("%d", flag?ans:-1);
return 0;
}

没有找零 状压dp的更多相关文章

  1. [BZOJ3312][USACO]不找零(状压DP)

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

  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. Codeforces 1225G - To Make 1(bitset+状压 dp+找性质)

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

  6. ZOJ3802 Easy 2048 Again (状压DP)

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

  7. LGTB与序列 状压dp

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

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

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

  9. 状压DP总结

    状态压缩就是将一行的状态压成一个二进制数,这个数的二进制形式反映了这一行的情况 比如0100111的意义为:这一排的第一个数没被使用,第二个被占用了,第三四个没被占用,第五六七个被占用 我们知道位运算 ...

随机推荐

  1. node.js+express验证码的实现

    安装ccap库 npm install ccap var ccap = require(); var captcha = ccap({ width:190, height:50, offset:30, ...

  2. 20179215《Linux内核原理与分析》第一周作业

    一.Linux介绍 我们现在很常见Windows系统,对于Linux则显得尤为陌生.当然我也不例外,初识Linux过程中遇到一些困惑,但我也在实验的同时通过不断查找资料与实践中慢慢解决问题.那么下面我 ...

  3. 第k小和(搜索)

    Description [问题描述] 从n个数中选若干(至少1)个数求和,求所有方案中第k小的和(和相同但取法不同的视为不同方案).[输入格式]    第一行输入2个正整数n,k.    第二行输入这 ...

  4. 51nod 1486 大大走格子——容斥

    题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1486 已知起点到某个障碍点左上角的所有点的不经过障碍的方案数,枚举 ...

  5. bzoj 5120 无限之环 & 洛谷 P4003 —— 费用流(多路增广SPFA)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5120 https://www.luogu.org/problemnew/show/P4003 ...

  6. 通用RowMapper封装查询结果到自定义类中

    package object; import java.lang.reflect.Field;import java.sql.ResultSet;import java.sql.SQLExceptio ...

  7. java继承示例

    package day07; class Fu { int num = 5; } class Zi extends Fu { int num =7; void show() { int num =9; ...

  8. uva 512

    1. 问题 不知道怎么存储操作 看代码注释,else if等 2. 代码 #include <iostream> #include <stdio.h> #include < ...

  9. HttpApplication 对象的创建过程及HttpModule过滤器的内部实现过程

    最近通过Reflector学习了一下asp.net内部的原理,做做笔记,方便以后查阅. 先看下HttpApplication 对象的创建过程 从IHttpHandler applicationInst ...

  10. 使用python+requests对接口进行测试

    import unittestimport requestsimport json class Login(unittest.TestCase): def setUp(self): self.base ...