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的更多相关文章

  1. 【BZOJ3312】[Usaco2013 Nov]No Change 状压DP+二分

    [BZOJ3312][Usaco2013 Nov]No Change Description Farmer John is at the market to purchase supplies for ...

  2. bzoj 3312: [Usaco2013 Nov]No Change

    3312: [Usaco2013 Nov]No Change Description Farmer John is at the market to purchase supplies for his ...

  3. bzoj3312: [Usaco2013 Nov]No Change

    题意: K个硬币,要买N个物品.K<=16,N<=1e5 给定买的顺序,即按顺序必须是一路买过去,当选定买的东西物品序列后,付出钱后,货主是不会找零钱的.现希望买完所需要的东西后,留下的钱 ...

  4. 【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 ...

  5. BZOJ3315: [Usaco2013 Nov]Pogo-Cow

    3315: [Usaco2013 Nov]Pogo-Cow Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 143  Solved: 79[Submit] ...

  6. BZOJ3314: [Usaco2013 Nov]Crowded Cows

    3314: [Usaco2013 Nov]Crowded Cows Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 86  Solved: 61[Subm ...

  7. 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 ...

  8. BZOJ 3314: [Usaco2013 Nov]Crowded Cows( 单调队列 )

    从左到右扫一遍, 维护一个单调不递减队列. 然后再从右往左重复一遍然后就可以统计答案了. ------------------------------------------------------- ...

  9. 3314: [Usaco2013 Nov]Crowded Cows

    3314: [Usaco2013 Nov]Crowded Cows Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 111  Solved: 79[Sub ...

随机推荐

  1. Flask(2):登陆验证

    装饰器补充: import functools def auth(func): @functools.wraps(func) # 作用:把原函数的原信息封装到 inner 中 def inner(*a ...

  2. csu - 1537: Miscalculation (模拟题)

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1537 因为给出的式子是必定合法的,只要用两个栈分别保存符号和数字.算出答案后和从左至右算的答案比对 ...

  3. Visual studio 2008 的语法高亮插件 WordLight

    前段时间一直在使用matlab,今天需要使用vs2008,而用惯了matlab,习惯了其中一项选中变量高亮的设置,突然回来使用VS,感到各种不适应,顿时想到了一个词:矫情 呵呵,于是在网上找各种插件, ...

  4. python加载和使用java的类的方法

    在开发python项目的时候,有时候会用的java的jar包 有这么几个python的三方包可以用: pyjnius:bug list:https://github.com/kivy/pyjnius/ ...

  5. samba服務器下文件夾chmod權限技巧

    需要的效果: samba下文件夹(abc)不可以被重命名.不可以被刪除,其所有子目录可读可写. 如何做到: chmod 777 -R abc   # -R 使得abc下所有数据继承可读可写权限 chm ...

  6. iOS_开发中遇到的那些问题_1

    [自编号:60][AutoLayout中,怎样让ImageView保持固定的宽高比?比如1:1] 先将imageViewframe手动写成:宽20,高20,再勾选Aspect Ratio加入宽高比约束 ...

  7. SDUTOJ 2476Period

    #include<iostream> #include<string.h> #include<stdio.h> #define N 1000010 using na ...

  8. Skype for Business七大新功能

    Lync Server 2013的下一版本号.Skype for Business将于2015年4月正式公布,下面是七大新功能. "呼叫监听"(Call Monitor)--假设你 ...

  9. Android如何进行单元测试

    Menifest.xml中加入: <application>中加入: <uses-library android:name="android.test.runner&quo ...

  10. 满足qps 同时兼顾 数据生产速率

    满足qps 同时兼顾  数据生产速率