其实我是点单调队列的标签进来的,之后看着题就懵逼了

于是就去题解里一翻,发现楼上楼下的题解说的都好有道理,

f[j]表示一个再使用一个硬币就能到达i的某个之前状态,b[now]表示使用那个能使状态j变到i的硬币的面值,find表示这些花费可以到达的最大距离,由于前缀和保持单调可以用二分求解,方程不就是f[i]=max(f[i],find(p[f[j]]+b[now]))吗

但这道题怎么用单调队列优化呢

我们观察这个方程你会发现无论是b[now],p[f[j]]都跟i没有什么关系,而只要是p[f[j]]+b[now]越大,相应的find的值也就越大

于是我们就可以愉快的单调队列优化这个dp了,用一个单调队列把每次的p[f[j]]+b[now]存起来,每次有新元素入队时维护队列的单调性,之后当所有元素入队完,直接用队首的最大值进行一遍find就好了,这样就可以避免进行多次find了

尽管单调队列是用常数奇大的deque实现的,但开了O2能跑到120 ms,轻松卡到最优解第一

#include<iostream>
#include<queue>
#include<cstring>
#include<cstdio>
#define re register
#define int long long
#define maxn 100001
using namespace std;
int f[65540],a[maxn],b[17],n,m,num,p[maxn];
int c[17];
inline void check(int x)
{
memset(c,0,sizeof(c));
int pp=m;
while(x)
{
if(x&1) c[pp]=1;
pp--;
x>>=1;
}
}
inline int read()
{
char c=getchar();
int x=0;
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9')
x=(x<<3)+(x<<1)+c-48,c=getchar();
return x;
}
inline int find(int x)
{
int l=1,r=n,tot=0;
while(l<=r)
{
int mid=l+r>>1;
if(p[mid]<=x) l=mid+1,tot=mid;
else r=mid-1;
}
return tot;
}
signed main()
{
m=read();
n=read();
for(re int i=1;i<=m;i++) b[i]=read(),num+=b[i];
for(re int i=1;i<=n;i++) a[i]=read();
p[1]=a[1];
for(re int i=2;i<=n;i++) p[i]=p[i-1]+a[i];
for(re int i=0;i<=(1<<m)-1;i++)
{
deque<int> q;
for(re int j=1;j<=m;j++)
{
if(!(i&(1<<(m-j)))) continue;//这里跟楼上楼下几篇题解不太一样,这个状态转成二进制后左边第一位表示的是第一个硬币是否被选择
int k=i^(1<<(m-j));
while(q.size()&&q.back()<p[f[k]]+b[j]) q.pop_back();//跟队尾元素比较,如果比队尾大就弹出队尾,维护单调队列单调性
q.push_back(p[f[k]]+b[j]);//入队
}
//其实这里不用单调队列优化也是可以的,我们只需要存储一下最大值就好了,这样应该还能快一些,但是用单调队列优化dp的这种思路还是比较重要的
f[i]=find(q.front());//只用一遍find就好了
}
int ans=-1;
for(re int i=0;i<=(1<<m)-1;i++)
{
if(f[i]!=n) continue;//当前状态根本到不了n,就直接下一个
check(i);//将当前的状态转成二进制数
int tot=0;
for(re int j=1;j<=m;j++)
if(c[j]==0) tot+=b[j];
//如果没有被选择,那么就把它加上
if(tot>ans) ans=tot;
}
cout<<ans;
return 0;
}

【[USACO13NOV]没有找零No Change】的更多相关文章

  1. [USACO13NOV]没有找零No Change [TPLY]

    [USACO13NOV]没有找零No Change 题目链接 https://www.luogu.org/problemnew/show/3092 做题背景 FJ不是一个合格的消费者,不知法懂法用法, ...

  2. 洛谷P3092 [USACO13NOV]没有找零No Change

    P3092 [USACO13NOV]没有找零No Change 题目描述 Farmer John is at the market to purchase supplies for his farm. ...

  3. P3092 [USACO13NOV]没有找零No Change

    题目描述 Farmer John is at the market to purchase supplies for his farm. He has in his pocket K coins (1 ...

  4. 洛谷 P3092 [USACO13NOV]没有找零No Change

    题目描述 Farmer John is at the market to purchase supplies for his farm. He has in his pocket K coins (1 ...

  5. luogu P3092 [USACO13NOV]没有找零No Change

    题目描述 Farmer John is at the market to purchase supplies for his farm. He has in his pocket K coins (1 ...

  6. P3092 [USACO13NOV]没有找零No Change 状压dp

    这个题有点意思,其实不是特别难,但是不太好想...中间用二分找最大的可买长度就行了. 题干: 题目描述 Farmer John <= K <= ), each with value .., ...

  7. Luogu P3092 [USACO13NOV]没有找零No Change【状压/二分】By cellur925

    题目传送门 可能是我退役/NOIP前做的最后一道状压... 题目大意:给你\(k\)个硬币,FJ想按顺序买\(n\)个物品,但是不能找零,问你最后最多剩下多少钱. 注意到\(k<=16\),提示 ...

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

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

  9. [洛谷P3092]【[USACO13NOV]没有找零No Change】

    状压\(DP\) + 二分 考虑构成:\(k<=16\)所以根据\(k\)构造状压\(dp\),将所有硬币的使用情况进行状态压缩 考虑状态:数组\(dp[i]\)表示用\(i\)状态下的硬币可以 ...

随机推荐

  1. Golang教程:常量

    定义常量 常量(constant)表示固定的值,比如:5,-89,"I love Go",67.89 等等. 考虑如下程序: var b string = "I love ...

  2. chmod修改文件的权限/chown修改文件和目录的所有者(转)

    ll指令的显示的信息为(当前目录下只有nameservice1一个目录): drwxr-xr-x 3 hdfs hdfs 4096 4月 14 16:19 nameservice1 上述信息分别表示: ...

  3. 常用工具说明--Git和GitHub简明教程

    一.Git的主要功能:版本控制 版本:想想你平时用的软件,在软件升级之后,你用的就是新版本的软件.你应该见过这样的版本号:v2.0 或者 1511(表示发布时为15年11月),如下图:那么如果你修改并 ...

  4. jQuery比较时间处理过程(日期转换为时间戳比较)

    不管在JS中还是PHP中,终会遇到时间比较,但是很尴尬的是,举个例子,2017-04-12和2017-5-21是不一样或者说不能比较的,这在PHP和JS都是这种情况,这种情况怎么办呢,换成统一的格式比 ...

  5. Docker 教程

    转自:http://www.runoob.com/docker/docker-tutorial.html Docker 教程

  6. vue本地设置请求接口及数据

    1.安装axios yarn add axios 2.在入口文件main.js中设置 import { getRequest, postRequest} from './libs/api';//导入 ...

  7. json转化的时候如何忽略某些属性字段值

    一.有时候在将对象或list对象转化为json的时候,我们可能不需要所有的属性值,这就需要我们去过滤掉这些属性了 我下面说两种比较流行的json包如何来忽略某些属性值 二. 使用jaskson包 1. ...

  8. ASID 与 MIPS 中 TLB 相关

    ASID 为了提高TLB的性能,将TLB分成Global和process-specific.global 是指常驻在tlb中不会被刷出的,例如内核空间的翻译,process-specific 是指每个 ...

  9. Be opinionated out of the box but get out of the way quickly as requirements start to diverge from

    Be opinionated out of the box but get out of the way quickly as requirements start to diverge from t ...

  10. lincode 题目记录5

    Course Schedule 安排课表   Frog Jump  最长回文字符串长度 Course Schedule 选课方案问题,题目说的很清楚了就是bfs或者dfs,然后加个字典优化,弄了好久没 ...