zoukankan      html  css  js  c++  java
  • codeforce The Art of Dealing with ATM

    题目大意

    ATM取款机有n种不同的钱币kind[i],每次取款允许吐出不超过k张钱币,且钱币的种类数不能超过2(一开始没理解2的意思),现在有q次取款,钱数为ques,问ATM能否凑出这样的钱,若能的话吐出的钱币数最少是多少。

    n <= 5000, k <= 20, q <= 20, kind[i] <= 10 ^ 7, ques <= 2 * 10 ^ 8。

    题解:

    用两种钱找零可以写成a * x + b * y = ques,其中x和y是两种钱币、a和b是两种钱币分别用的钱数、ques是所需凑出的钱数,则最优的解法是枚举x, a, b,判断y是否在钱的种类中,主要x或者y可以为0;

    一开始想的用搜索,果断试了一下,果然超时;

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<queue>
    #include<stack>
    #include<string>
    #include<algorithm>
    #define maxn 1001
    #define INF ~0u >> 1
    using namespace std;
    int n,k,vist[10000004],kind[6000];
    int ans;
    int main()
    {
    int q,ques;
    scanf("%d %d",&n,&k);
    memset(vist,0,sizeof(vist));
    for(int i=1; i<=n; i++)
    {
    scanf("%d",&kind[i]);
    vist[kind[i]]=1;

    }
    scanf("%d",&q);
    for(int ii=1; ii<=q; ii++)
    {
    scanf("%d",&ques);
    ans=INF;
    for(int i=0; i<=k; i++)
    {
    for(int j=0; j+i<=k; j++)
    {
    for(int t=1; t<=n; t++)
    {
    if(j==0)
    {
    if(kind[t]*i==ques)
    ans=min(ans,i);
    }
    else
    {
    int b=(ques-kind[t]*i)/j;
    if(b>0&&b<=10000000&&vist[b]&&kind[t]*i+b*j==ques)
    ans=min(ans,i+j);
    }

    }
    }
    }
    if(ans==INF)
    printf("-1 ");
    else
    printf("%d ",ans);
    }

    return 0;
    }

  • 相关阅读:
    小X的密码破译
    小X的加法难题
    足球联赛
    机器分配
    化装晚会
    Soundex编码
    迷之阶梯
    使用JMeter做压力测试
    SCOI 2010 序列操作
    动态求区间K大值(权值线段树)
  • 原文地址:https://www.cnblogs.com/tsw123/p/4368136.html
Copyright © 2011-2022 走看看