• BZOJ 4265 货币系统


    今天比赛的时候做到的。题解写得很简单,但是感觉对于我这种蒟蒻还是很有思考的价值的。

    题面(由于题面很短,就不概括了):小Q当上了新的宇宙大总统,他现在准备重新设计一套货币系统。

    这个货币系统要求一共有m张货币,并且将他们按照币值从小到大排好序以后,前一个货币币值乘上x等于后一个货币币值,x∈{2,3,4,5},最小的币值为1。
    小Q出门喜欢带总币值为n的钱,因为这是他的幸运数字,所以他希望设计出来的货币系统可以使得他带最少张数的货币。
    数据范围:1≤n≤10^18 1≤k≤100

    这道题(权限题),拿到的时候给人一种隐约的背包感。数据范围让小蒟蒻我想到DP+矩阵乘法/二分。然而这些都只是YY,我们仔细分析一下题面,可以先将其简(fu za)化为以下这个问题(ki∈{2,3,4,5},ai∈N*):
    n=1*(a1+k1*(a2+k2*(a3+k3*(a4+k4*a5)))) 求出min(a1+a2+a3+a4+a5) (为了方便叙述,取m=5讨论)

    这个还是比较好理解的。5个面值分别为1,k1,k1*k2,k1*k2*k3,k1*k2*k3*k4,5个面值各取a1,a2,a3,a4,a5张,把这个式子拆开就可以证明其正确性。然后我们可以得到,a2=(m-a1)/k2,后面的a3,a4,a5也是同理。

    然后到这里小蒟蒻卡了一下。

    反着考虑。假设我们已经得到所有货币的面值,肯定是从大到小贪心地取。因为 货币i 的一张等同于ki-1张 货币i-1 ,所以ai-1<ki-1 。因此,我们可以枚举ki,然后倒过来将n· 对ki的余数(也就是ai)计入答案,再将n·除以ki得到下一个n· ,直到除的次数(即k)用完。

    因此,我们可以得到下面这个会T的算法(也就是小蒟蒻考试的时候上交的算法):

     1 #define ll long long
     2 ll n;
     3 int k;
     4 ll dfs(ll xz,int cs){//xz表示当前值,cs表示还剩多少次
     5     if(xz==0)return 0;
     6     if(cs==1)return xz; 
     7     ll mi=1e18,ans;
     8     for(ll i=2;i<=5;i++){
     9         ans=dfs(xz/i,cs-1)+xz%i;
    10         if(ans<mi)mi=ans;
    11     }
    12     return mi;
    13 }
    14 int main(){
    15     scanf("%lld%d",&n,&k);
    16     printf("%lld",dfs(n,k));
    17 }

    然后我就T了……

    T了……

    事实上,只要用map记忆化就可以了……怎么说呢……被自己蠢到了……

    AC代码如下:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 ll n;
     5 int k;
     6 map<ll,ll>m[105];
     7 ll dfs(ll xz,int cs){
     8     if(m[cs].count(xz))return m[cs][xz];
     9     if(xz==0)return 0;
    10     if(cs==1)return xz; 
    11     ll mi=1e18,ans;
    12     for(ll i=2;i<=5;i++){
    13         ans=dfs(xz/i,cs-1)+xz%i;
    14         if(ans<mi)mi=ans;
    15     }
    16     return m[cs][xz]=mi;
    17 }
    18 int main(){
    19     scanf("%lld%d",&n,&k);
    20     printf("%lld",dfs(n,k));
    21 }

    以此篇博客为戒,多存套路,少犯智障错误。

  • 相关阅读:
    Python-02 可视化之tkinter介绍
    Python-01矩阵、数组和列表等的总结
    嵌入式文件IO实验
    Linux 学习
    linux 学习
    Linux学习
    Linux学习
    Linux 学习
    Linux 学习
    Linux 用户权限学习
  • 原文地址:https://www.cnblogs.com/BLeaves/p/8684376.html
Copyright © 2020-2023  润新知