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
*/
二进制优化

相关文章:

  • 2021-10-17
  • 2022-12-23
  • 2022-12-23
  • 2021-07-15
  • 2022-03-06
  • 2021-11-11
  • 2022-02-26
  • 2021-07-25
猜你喜欢
  • 2021-10-01
  • 2021-08-17
  • 2022-12-23
  • 2021-10-28
  • 2022-12-23
  • 2021-12-06
  • 2021-07-23
相关资源
相似解决方案