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;
}

最新文章

  1. [super init]方法的调用
  2. PAT1076. Forwards on Weibo(标准bfs模板)
  3. AppServ 配置还是成功了
  4. 关于ACM,关于CSU
  5. E - 小晴天老师系列——我有一个数列!
  6. oc 是否允许远程通知
  7. 表单验证插件--formvalidation
  8. Vim8.0在Debian下,normal模式的O命令出现延时
  9. 王家林人工智能AI课程大纲和电子书 - 老师微信13928463918
  10. SSM实现秒杀系统案例
  11. java的clone()方法
  12. Android日常问题整理
  13. topcoder srm 525 div1
  14. python中的print()、str()和repr()的区别
  15. 进程创建过程详解 CreateProcess
  16. 进阶之路(基础篇) - 019 Serial串口函数说明
  17. 如何设置IIS程序池的回收时间,才能最大程度的减少对用户的影响?
  18. JUnit规则
  19. 织梦dedecms模板制作时,循环递增autoindex使用方法整理
  20. 2015309南皓芯《Java程序设计》实验一(Java开发环境的熟悉)实验报告

热门文章

  1. [NOIP2004] 提高组 洛谷P1089 津津的储蓄计划
  2. python 安装依赖几个问题---HttpScan
  3. Servlet开发(3)
  4. Android GIS开发系列计划
  5. Elasticsearch学习系列之介绍安装
  6. php设计模式——模板模式
  7. vue中slot的笔记
  8. powershell 的版本号所引起的载入 FSharp 编译器问题
  9. 工作总结 js for 循环遍历 json 数据
  10. python爬虫【第1篇】