P3092 [USACO13NOV] No Change G 题解
题解
思路
看到 \(1\le k\le16\),我们想到状压DP。
以每枚硬币是否被使用为状态,对其进行枚举。
令 \(dp_i\) 表示状态 \(i\) 下最多能支付到第 \(dp_i\) 件商品,令 \(f_{i,j}\) 表示从第 \(i+1\) 个位置开始,第 \(j\) 枚硬币可以支付 \((i+1,f_{i,j}]\) 这一区间的商品。
于是可以知道:每个状态下最多能支付到的商品位置,是从它的前继状态最多能支付到的那件商品的下一件商品开始,使用新增加的那枚硬币,所能支付到的最后一件商品的位置。
结合转移方程理解这句话:
\]
写成代码形式:
if(i&(1<<j)==0) dp[i]=max(dp[i],f[dp[i^(1<<j)][j];
像这样。答案就是所有 \(dp_i\ge N\) 的状态中剩余钱数的最小值。
时间复杂度 \(O(NK\log N+2^KK)\),可以解决。
实现
首先需要预处理 \(f\) 数组。笔者使用二分,更优的做法是双指针,留给读者自行思考(绝对不是因为我不会)。
在预处理过程中需要频繁查询区间和,因此可以预处理 \(c\) 数组的前缀和。
代码
#include <cstdio>
#define N 100005
int max(int x,int y) {return x>y?x:y;}
int k,n;
int a[20],c[N];
int f[N][20]; //(i,f[i][k]]
int dp[N];
int cnt(int x) //没用的硬币求和
{
int ret=0;
for(int i=0;i<k;i++)
if(!(x&(1<<i))) ret+=a[i];
return ret;
}
int main()
{
scanf("%d%d",&k,&n);
for(int i=0;i<k;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
scanf("%d",&c[i]),c[i]+=c[i-1];
for(int i=0;i<=n;i++)
for(int j=0;j<k;j++)
{
int lb=i,rb=n;
while(lb<rb)
{
int mid=lb+rb+1>>1;
if(c[mid]-c[i]<=a[j]) lb=mid;
else rb=mid-1;
}
f[i][j]=lb;
}
int maxc=-1;
for(int i=0;i<(1<<k);i++)
{
for(int j=0;j<k;j++)
if(i&(1<<j))
dp[i]=max(dp[i],f[dp[i^(1<<j)]][j]);
if(dp[i]==n)
maxc=max(maxc,cnt(i));
}
printf("%d",maxc);
}
\]
P3092 [USACO13NOV] No Change G 题解的更多相关文章
- 洛谷P3092 [USACO13NOV]没有找零No Change
P3092 [USACO13NOV]没有找零No Change 题目描述 Farmer John is at the market to purchase supplies for his farm. ...
- 状压 DP:[USACO06NOV] Corn Fields,[USACO13NOV] No Change
[USACO06NOV] Corn Fields (试题来源:Link ) 题目描述 Farmer John has purchased a lush new rectangular pasture ...
- 洛谷P3104 Counting Friends G 题解
题目 [USACO14MAR]Counting Friends G 题解 这道题我们可以将 \((n+1)\) 个边依次去掉,然后分别判断去掉后是否能满足.注意到一点, \(n\) 个奶牛的朋友之和必 ...
- 洛谷P2115 Sabotage G 题解
题目 [USACO14MAR]Sabotage G 题解 本蒟蒻又来了,这道题可以用二分答案来解决.我们可以设答案最小平均产奶量为 \(x \ (x \in[1,10000])\) .然后二分搜索 \ ...
- P3092 [USACO13NOV]没有找零No Change
题目描述 Farmer John is at the market to purchase supplies for his farm. He has in his pocket K coins (1 ...
- 洛谷 P3092 [USACO13NOV]没有找零No Change
题目描述 Farmer John is at the market to purchase supplies for his farm. He has in his pocket K coins (1 ...
- 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 ...
- P3092 [USACO13NOV]没有找零No Change 状压dp
这个题有点意思,其实不是特别难,但是不太好想...中间用二分找最大的可买长度就行了. 题干: 题目描述 Farmer John <= K <= ), each with value .., ...
- Luogu P3092 [USACO13NOV]没有找零No Change【状压/二分】By cellur925
题目传送门 可能是我退役/NOIP前做的最后一道状压... 题目大意:给你\(k\)个硬币,FJ想按顺序买\(n\)个物品,但是不能找零,问你最后最多剩下多少钱. 注意到\(k<=16\),提示 ...
- P2882 Face The Right Way G 题解
题目 Farmer John has arranged his N \((1 ≤ N ≤ 5,000)\) cows in a row and many of them are facing forw ...
随机推荐
- 藏不住了,这届数字打工人(RPA)想在各行各业“当骨干”!
数字化时代,最红的"打工人"是谁? 无疑,是RPA(数字化劳动力). 这种由机器人流程自动化+AI驱动,模拟人点击.移动鼠标等在电脑上的操作,在各种规则明确.高重复度业务场景中代替 ...
- 【Python】【Pandas】使用concat添加行
添加行 t = pd.DataFrame(columns=["姓名","平均分"]) t = t.append({"姓名":"小红 ...
- IDEA和GIT关于文件中LF和CRLF问题
问题描述:项目软件安装shell脚本上git仓库管理,但拉取后,上linux运行报错. 问题思考:根据描述信息可以查看到\r字样,初步判别为换行符导致 1.将脚本文件移动至notepad++中,通过视 ...
- Qt编写物联网管理平台38-多种数据库支持
一.前言 本系统设计之初就要求支持多种不同的数据库,比如sqlite.mysql.postgres.sqlserver等,甚至包括国产数据库比如人大金仓kingbase等,(由于现在国产化的大力推进, ...
- Qt编写的项目作品22-自定义委托全家桶
一.功能特点 可设置多种委托类型,例如复选框/文本框/下拉框/日期框/微调框/进度条等. 可设置是否密文显示,一般用于文本框. 可设置是否允许编辑,一般用于下拉框. 可设置是否禁用,一般用来禁用某列. ...
- 《Spring Boot+Vue全栈开发实战-王松2018》一书pdf+源码下载
下载地址为: 链接:https://pan.baidu.com/s/18lnF2KemQTqkKaCRmMbvXA 提取码:1pie 版权声明:本书版权属于出版社和作者.仅学习使用,请于下载后24小时 ...
- matlab中mat文件的生成和读取
1.mat文件的生成 (1)直接在Matlab中创建并保存矩阵数据 打开Matlab软件,点击左上角文件(File),然后点击新建(new),选择变量(Variable),就新建了一个mat文件. 点 ...
- Java GUI控件SwingX之JXTaskPane的使用示例
JXTaskPane 类似XP 左边的导航栏,在开发Swing应用的时候很好用的.下面两张截图反应了JXTaskPane的动画效果.可以自由的卷起和展开. JXTaskPane的的使用步骤:1.新 ...
- 开源 Material Design WPF UI 控件库,易用且功能强大
前言 Material Design 是由 Google 开发的一套设计指南,提供统一的设计语言,使用户界面更加直观.美观和一致. Material Design In XAML Toolkit 是一 ...
- Jetbrain Fleet体验版linxu环境开发Python初体验
Jetbrain Fleet体验版linxu环境开发Python初体验 (base) linxu@linxu-PC:~/Projects/FleetProjects$ conda activate d ...