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+;
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=;i<=n;i++)
scanf("%d",&dat[i]),mx=max(mx,dat[i]),tot+=dat[i]; mn[]=;
for(int i=;i<=mx;i++) //线性筛
{
if(!vis[i]) pri[++cnt]=i,mn[i]=i;
for(int j=;j<=cnt && i*pri[j]<=mx;j++)
{
vis[i*pri[j]]=;mn[i*pri[j]]=pri[j];
if(i%pri[j]==) break;
}
} for(int i=;i<=mx;i++) dp[i]=tot;res=tot;
for(int i=;i<=mx;res=min(res,dp[i]),i++)
for(int j=i;j>;dp[i]=min(dp[i],t))
{
t=dp[i/mn[j]];
for(int k=;k<=n;k++) t-=dat[k]/i*(mn[j]-);
while(mn[j]==mn[j/mn[j]]) j/=mn[j];
j/=mn[j];
}
printf("%d",res);
return ;
}

Review:

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

只能算是常数上的优化吧

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

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

推导的方式

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

2、$dp$的思考技巧

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

[BZOJ 3233] 找硬币的更多相关文章

  1. BZOJ 3233: [Ahoi2013]找硬币

    BZOJ 3233: [Ahoi2013]找硬币 标签(空格分隔): OI-BZOJ OI-DP Time Limit: 10 Sec Memory Limit: 64 MB Description ...

  2. BZOJ 3233: [Ahoi2013]找硬币( dp )

    dp(x)表示最大面值为x时需要的最少硬币数. 枚举x的质因数p,  dp(x) = min( dp(x/p) - (p-1) * sigma[a[i]/x] ). ----------------- ...

  3. [Bzoj3233][Ahoi2013]找硬币[基础DP]

    3233: [Ahoi2013]找硬币 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 924  Solved: 482[Submit][Status][ ...

  4. [AHOI2013]找硬币(搜索)

    [Ahoi2013]找硬币 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 348  Solved: 114[Submit][Status] Descri ...

  5. [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash)

    [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash) 题面 扔很多次硬币后,用H表示正面朝上,用T表示反面朝上,会得到一个硬币序列.比如HTT表示第一次正面朝上, ...

  6. 【bzoj 3233】[Ahoi2013]找硬币 ——搜索

    Description 小蛇是金融部部长.最近她决定制造一系列新的货币.假设她要制造的货币的面值为x1,x2,x3… 那么x1必须为1,xb必须为xa的正整数倍(b>a).例如 1,5,125, ...

  7. 【BZOJ 3233】 [Ahoi2013]找硬币

    [题目 描述] 小蛇是金融部部长. 最近她决定制造一系列新的货币. 假设她要制造的货币 的面值为 x1, x2, x3… 那么 x1 必须为 1, xb 必须为 xa 的正整数倍(b>a). 例 ...

  8. 【bzoj3233】【ahoi2013】找硬币

    题意: 求确定n种货币面额x1..xn满足 x1=1 且xi为xj的整数倍(i>j) 给定n个物品价格ai 求使用上面货币最少需要硬币数(不能找零) 题解: 动态规划 听说网上的题解都是搜索的做 ...

  9. [BZOJ 1042] [HAOI2008] 硬币购物 【DP + 容斥】

    题目链接:BZOJ - 1042 题目分析 首先 Orz Hzwer ,代码题解都是看的他的 blog. 这道题首先使用DP预处理,先求出,在不考虑每种硬币个数的限制的情况下,每个钱数有多少种拼凑方案 ...

随机推荐

  1. 【BZOJ 4605】崂山白花蛇草水 替罪羊树套线段树

    外层是借鉴了kd-tree的替罪羊里层是线段树,插入就是正常插入+拍扁重建,查询的时候,我们就像树状数组套线段树一样操作在替罪羊中找到的线段树根节点,但是对于在kd-tree查找过程中遇到的单点,我们 ...

  2. 如何在数据访问层上提高js的执行效率

    本文讲到的是如何从数据访问层面上提高JS 代码的执行效率.总的来讲有以下几条原则: 函数中读写局部变量总是最快的,而全局变量的读取则是最慢的: 尽可能地少用with 语句,因为它会增加with 语句以 ...

  3. fastjson解析服务端返回的数据

    1.配置依赖 //fastjson api 'com.alibaba:fastjson:1.2.44' 2.设计服务端返回的数据 {},{},{}]} 3.编写bean类,特别注意,要和服务端返回的类 ...

  4. 自己实现的JDBC工具类

    最近做了个后台应用程序,刚开始用Spring+iBatis来做的,后来因为种种原因,不让用Spring.iBatis以及一些开源的工具包.   于是用JDBC重写了原来的Service实现,项目做完了 ...

  5. SCC模板

    vector<int> G[maxn]; int pre[maxn], low[maxn], c[maxn]; int n, m; stack<int> s; int dfst ...

  6. Django项目知识点汇总

    目录 一.wsgi接口 二.中间件 三.URL路由系统 四.Template模板 五.Views视图 六.Model&ORM 七.Admin相关 八.Http协议 九.COOKIE 与 SES ...

  7. usaco 2000 contest 滑雪

    2013-09-11 10:22 [题目大意]给定N个点的高度和M条相连的路线(单向),从最高点向下走, 到无法走时为一条路径,求不同的路径数,(一节点不同就叫不同) [输入样例] 4 5   (N, ...

  8. bzoj 1834

    网络流的模板题 首先第一问我们直接用dinic搞就行了,费用直接存为0(时间上界非常松,这道题是能过),然后第二问我们只需要在第一问 的残余网络上加一个源点,源点指向1号点,容量为k,费用为0,然后对 ...

  9. wget.vbs & wget.ps1

    Wget-like tool for file transfer when do post exploitation. CODE echo strUrl = WScript.Arguments.Ite ...

  10. python的class的__str__和__repr__(转)

    本文参考自: https://stackoverflow.com/questions/18393701/the-difference-between-str-and-repr?noredirect=1 ...