zoukankan      html  css  js  c++  java
  • [BZOJ 3233] 找硬币

    Link:

    BZOJ 3233 传送门

    Solution:

    在本蒟蒻看来算是一道比较神的$dp$了

    一开始转移方程都没看出来……

    首先,如果确定了最大面值,是能推出其他面值的所有可能值的

    从而发现最大面值能由较小的面值转移过来:

    $dp[i]=min{ dp[i/j]-sum{ a[k]/i*(j-1)} }$

    (其中$a[k]/i$是大面值需要的个数,$a[k]/(i/j)$是小面值需要的个数,余数不处理)

    下面就要处理$j$的取值了,

    首先要看到一个比较明显的性质:用$dp[i]$转移肯定不会比用$dp[i/j]$差,毕竟种类更多

    于是$j$应为质数($i$的质因数),否则$i/j<i/MinPrime$,从而$dp[i/MinPrime]$一定不比$dp[i/j]$差

    因此不取合数对答案没有影响

    在线性筛时可以顺便求出$x$的最小质因数$mn[x]$,方便后面求出$x$的每一个质因数

    Code:

    #include <bits/stdc++.h>
    
    using namespace std;
    const int MAXN=1e5+10;
    int n,tot,mx,cnt,t,mn[MAXN],dat[MAXN],pri[MAXN],vis[MAXN],dp[MAXN],res;
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&dat[i]),mx=max(mx,dat[i]),tot+=dat[i];
        
        mn[1]=1;
        for(int i=2;i<=mx;i++) //线性筛
        {
            if(!vis[i]) pri[++cnt]=i,mn[i]=i;
            for(int j=1;j<=cnt && i*pri[j]<=mx;j++)
            {
                vis[i*pri[j]]=1;mn[i*pri[j]]=pri[j];
                if(i%pri[j]==0) break;
            }
        }
        
        for(int i=1;i<=mx;i++) dp[i]=tot;res=tot;
        for(int i=2;i<=mx;res=min(res,dp[i]),i++)
            for(int j=i;j>1;dp[i]=min(dp[i],t))
            {
                t=dp[i/mn[j]];
                for(int k=1;k<=n;k++) t-=dat[k]/i*(mn[j]-1);
                while(mn[j]==mn[j/mn[j]]) j/=mn[j];
                j/=mn[j];
            }
        printf("%d",res);
        return 0;
    }

    Review:

    1、关于质因数分解的优化

    只能算是常数上的优化吧

    由于筛法时我们要保证合数只被自己的最小质因数筛去,

    于是我们顺便记录下每个数最小的质因数$mn[x]$,再一步步推出下一个质因数

    推导的方式

    while(mn[j]==mn[j/mn[j]]) j/=mn[j];
    j/=mn[j];

    2、$dp$的思考技巧

    如果不清楚对什么量$dp$,可以查找那些量可以推出上一步/下一步的值,往往对这些量$dp$

  • 相关阅读:
    3.6 符号表的应用
    将博客搬至CSDN
    webpack打包vue项目IE报错,“对象不支持“use”属性或方法”
    移动端解决input被输入法挡住的问题
    javascript中对象的深复制的几种方法
    如何随机洗牌一个数组
    setInterval中this指向的问题
    css中的各种常见布局写法
    vue设置全局变量或函数
    【nodejs爬虫】使用async控制并发写一个小说爬虫
  • 原文地址:https://www.cnblogs.com/newera/p/9239139.html
Copyright © 2011-2022 走看看