[bzoj1531][POI2005]Bank notes
Posted Aireen Ye
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[bzoj1531][POI2005]Bank notes相关的知识,希望对你有一定的参考价值。
Description
拥有一套先进的货币系统,这个系统一共有种面值的硬币,面值分别为.但是每种硬币有数量限制,现在我们想要凑出面值求最少要用多少个硬币.
Input
第一行一个数.
第二行个整数.
第三行个整数,表示每种硬币的个数.
最后一行一个数,表示要凑的面值数量.
Output
一行一个数,表示最少需要付的硬币数.
Sample Input
32 3 5
2 2 1
10
Sample Output
3
HINT
Solution
表示用前种硬币凑出价值所需最少硬币数.
对于对取模结果相同的,可以用单调队列进行优化.
#include<cmath> #include<ctime> #include<queue> #include<stack> #include<cstdio> #include<vector> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define N 205 #define M 20005 using namespace std; int f[N][M],b[N],c[N],q[M],h,t,n,m; inline void init(){ scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&b[i]); for(int i=1;i<=n;++i) scanf("%d",&c[i]); scanf("%d",&m); for(int i=0;i<=n;++i) for(int j=1;j<=m;++j) f[i][j]=M; for(int i=1;i<=n;++i){ for(int k=0;k<b[i];++k){ h=1;t=0; for(int j=k;j<=m;j+=b[i]){ while(h<=t&&(j-q[h])/b[i]>c[i]) ++h; q[++t]=j; while(h<t&&f[i-1][q[t]]<=f[i-1][q[t-1]]+(j-q[t-1])/b[i]){ q[t-1]=q[t];--t; } f[i][j]=min(f[i-1][q[h]]+(j-q[h])/b[i],M); } } } printf("%d\n",f[n][m]); } int main(){ freopen("bag.in","r",stdin); freopen("bag.out","w",stdout); init(); fclose(stdin); fclose(stdout); return 0; }
以上是关于[bzoj1531][POI2005]Bank notes的主要内容,如果未能解决你的问题,请参考以下文章
bzoj1529 [POI2005]ska Piggy banks
luogu P3423 [POI2005]BAN-Bank Notes
bzoj1529: [POI2005]ska Piggy banks