[Usaco2013 Nov]No Change
Description
Farmer John is at the market to purchase supplies for his farm. He has in his pocket K coins (1 <= K <= 16), each with value in the range 1..100,000,000. FJ would like to make a sequence of N purchases (1 <= N <= 100,000), where the ith purchase costs c(i) units of money (1 <= c(i) <= 10,000). As he makes this sequence of purchases, he can periodically stop and pay, with a single coin, for all the purchases made since his last payment (of course, the single coin he uses must be large enough to pay for all of these). Unfortunately, the vendors at the market are completely out of change, so whenever FJ uses a coin that is larger than the amount of money he owes, he sadly receives no changes in return! Please compute the maximum amount of money FJ can end up with after making his N purchases in sequence. Output -1 if it is impossible for FJ to make all of his purchases.
K个硬币,要买N个物品。
给定买的顺序,即按顺序必须是一路买过去,当选定买的东西物品序列后,付出钱后,货主是不会找零钱的。
现希望买完所需要的东西后,留下的钱越多越好,如果不能完成购买任务,输出-1
Input
- Line 1: Two integers, K and N.
- Lines 2..1+K: Each line contains the amount of money of one of FJ's coins.
- Lines 2+K..1+N+K: These N lines contain the costs of FJ's intended purchases.
Output
- Line 1: The maximum amount of money FJ can end up with, or -1 if FJ cannot complete all of his purchases.
Sample Input
3 6
12
15
10
6
3
3
2
3
7
Sample Output
12
按顺序来这一点保证了我们能够对一枚硬币买到的东西一定是一段区间,那么我们就可以找到一个起始点来二分查找结束点。设F[sta]表示使用的硬币状态为sta,所能买到的最多的物品个数,每次转移时枚举一个没用过的硬币,从F[sta]开始向后买尽可能多的东西,结束点可以使用二分来找到。
\(F[sta|(1<<(i-1))]=max(F[sta|(1<<(i-1))],find(F[sta],coin[i]));\)
/*program from Wolfycz*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline int read(){
int x=0,f=1;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
inline void print(int x){
if (x>=10) print(x/10);
putchar(x%10+'0');
}
const int N=1e5;
int val[N+10],sum[N+10];
int f[(1<<17)+10],A[20];
int limit;
int find(int x,int k){
k+=sum[x];
int l=x+1,r=limit;
while (l<=r){
int mid=(l+r)>>1;
if (k<sum[mid]) r=mid-1;
else l=mid+1;
}
return l-1;
}
int main(){
int k=read(),n=read(),Ans=-inf; limit=n;
for (int i=1;i<=k;i++) A[i]=read();
for (int i=1;i<=n;i++) sum[i]=sum[i-1]+(val[i]=read());
memset(f,255,sizeof(f));
f[0]=0;
for (int sta=0;sta<1<<k;sta++){
if (f[sta]==-1) continue;
if (f[sta]==n){
int res=0;
for (int i=1;i<=k;i++) if (!(sta&(1<<(i-1)))) res+=A[i];
Ans=max(Ans,res);
}
for (int i=1;i<=k;i++){
if (sta&(1<<(i-1))) continue;
f[sta|(1<<(i-1))]=max(f[sta|(1<<(i-1))],find(f[sta],A[i]));
}
}
printf("%d\n",Ans==-inf?-1:Ans);
return 0;
}
[Usaco2013 Nov]No Change的更多相关文章
- 【BZOJ3312】[Usaco2013 Nov]No Change 状压DP+二分
[BZOJ3312][Usaco2013 Nov]No Change Description Farmer John is at the market to purchase supplies for ...
- bzoj 3312: [Usaco2013 Nov]No Change
3312: [Usaco2013 Nov]No Change Description Farmer John is at the market to purchase supplies for his ...
- bzoj3312: [Usaco2013 Nov]No Change
题意: K个硬币,要买N个物品.K<=16,N<=1e5 给定买的顺序,即按顺序必须是一路买过去,当选定买的东西物品序列后,付出钱后,货主是不会找零钱的.现希望买完所需要的东西后,留下的钱 ...
- 【bzoj3312】[Usaco2013 Nov]No Change 状态压缩dp+二分
题目描述 Farmer John is at the market to purchase supplies for his farm. He has in his pocket K coins (1 ...
- BZOJ3315: [Usaco2013 Nov]Pogo-Cow
3315: [Usaco2013 Nov]Pogo-Cow Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 143 Solved: 79[Submit] ...
- BZOJ3314: [Usaco2013 Nov]Crowded Cows
3314: [Usaco2013 Nov]Crowded Cows Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 86 Solved: 61[Subm ...
- BZOJ 3315: [Usaco2013 Nov]Pogo-Cow( dp )
我真想吐槽USACO的数据弱..= = O(n^3)都能A....上面一个是O(n²), 一个是O(n^3) O(n^3)做法, 先排序, dp(i, j) = max{ dp(j, p) } + w ...
- BZOJ 3314: [Usaco2013 Nov]Crowded Cows( 单调队列 )
从左到右扫一遍, 维护一个单调不递减队列. 然后再从右往左重复一遍然后就可以统计答案了. ------------------------------------------------------- ...
- 3314: [Usaco2013 Nov]Crowded Cows
3314: [Usaco2013 Nov]Crowded Cows Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 111 Solved: 79[Sub ...
随机推荐
- codevs1792 分解质因数
题目描述 Description 编写一个把整数N分解为质因数乘积的程序. 输入描述 Input Description 输入一个整数 N 输出描述 Output Description 输出 分解质 ...
- poj_2506_Tiling_201407211555
Tiling Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7509 Accepted: 3672 Descriptio ...
- Codeforces 621E Wet Shark and Block【dp + 矩阵快速幂】
题意: 有b个blocks,每个blocks都有n个相同的0~9的数字,如果从第一个block选1,从第二个block选2,那么就构成12,问对于给定的n,b有多少种构成方案使最后模x的余数为k. 分 ...
- BZOJ——2190: [SDOI2008]仪仗队
思路: 我们将其所在的位置设为(0,0),那么如果存在一个点(x,y),且有gcd(x,y)=k(k!=1),那么点(x/k,y/k)一定会将(x,y)挡住.而如果k=1,那么点(x,y)就一定会被看 ...
- Java函数式接口Function
Function 提供了一个抽象方法 R apply(T t) 接收一个参数 返回 一个值,还有两个默认方法和一个静态方法 compose 是一个嵌套方法,先执行before.apply() 得到运 ...
- GDAL源码编译
转自阿Fai, GDAL源码编译 在这里,我使用源码编译出C#可以使用的dll静态文件. 一.简单的编译 1.简单的认识 首先进入GDAL的源代码目录,可以看到有几个sln为后缀的文件名,比如make ...
- react的类型检查PropTypes自React v15.5起已弃用,请使用prop-types
最近使用React的类型检查PropTypes时,遇到错误:TypeError: Cannot read property 'array' of undefined 看了下自己的React版本: ...
- POJ3977 Subset 折半枚举
题目大意是给定N个数的集合,从这个集合中找到一个非空子集,使得该子集元素和的绝对值最小.假设有多个答案,输出元素个数最少的那个. N最多为35,假设直接枚举显然是不行的. 可是假设我们将这些数分成两半 ...
- 介绍css 的3D 变换(3D transform)
https://desandro.github.io/3dtransforms/docs/card-flip.html ---------------------------------------- ...
- 使用Java快速开发博客、官网等偏内容型网站-IDEA篇-MCMS
分享快乐 由于官网提供的是eclipse的教学视频,清晰度感人,看得我就一个纳闷,反复的看,反复检查,就是不行,然后天真的寻觅帮助,反复查看文档依旧凉凉.最后放弃,转战idea.特此篇,希望能帮助到各 ...