1601:【例 5】Banknotes
时间限制: 1000 ms 内存限制: 524288 KB【题目描述】
原题来自:POI 2005
Byteotian Bit Bank (BBB) 拥有一套先进的货币系统,这个系统一共有 ,求最少要用多少个硬币。
【输入】
第一行一个数 n;
接下来一行 ;
第三行 ,表示每种硬币的个数;
最后一行一个数 ,表示要凑的面值数。
【输出】
第一行一个数表示最少需要付的硬币数。
【输入样例】
3
2 3 5
2 2 1
10
【输出样例】
3
【提示】
数据范围与提示:
对于全部数据, 。
sol:比较裸的完全背包??可以有两种优化:
二进制优化太水不说了
#include <bits/stdc++.h> using namespace std; typedef int ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } inline void writeln(ll x) { write(x); putchar('\n'); return; } #define W(x) write(x),putchar(' ') #define Wl(x) writeln(x) const int N=20005,M=2000005; int n,m,B[N],C[N],dp[M]; int main() { int i,j,k; R(n); for(i=1;i<=n;i++) R(B[i]); for(i=1;i<=n;i++) R(C[i]); R(m); memset(dp,63,sizeof dp); dp[0]=0; for(i=1;i<=n;i++) { for(j=1;j<=C[i]&&j*B[i]<=m;j<<=1) { for(k=m;k>=j*B[i];k--) dp[k]=min(dp[k],dp[k-j*B[i]]+j); } } Wl(dp[m]); return 0; } /* input 3 2 3 5 2 2 1 10 output 3 input 10 6 17 111 249 250 495 496 497 498 499 100 100 100 100 1 100 100 100 100 100 500 output 6 input 3 300 700 4800 10000 10000 10000 5000 output 10 */