[Bzoj3233][Ahoi2013]找硬币[基础DP]
3233: [Ahoi2013]找硬币
Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 924 Solved: 482
[Submit][Status][Discuss]
Description
Input
Output
一行,一个整数,表示最少付的钱币数。
Sample Input
Sample Output
HINT
样例解释:共有两只兔纸,价钱分别为25和102。现在小蛇构造1,25,100这样一组硬币序列,那么付第一只兔纸只需要一个面值为25的硬币,第二只兔纸需要一个面值为100的硬币和两个面值为1的硬币,总共两只兔纸需要付4个硬币。这也是所有方案中最少所需要付的硬币数。
1<=N<=50, 1<=ai<=100,000
分析:
本来凑面值的题就是十分亲民的题,再加上数据又十分亲民,所以就是一道十分亲民的题……。
定义状态f[i]表示最大硬币为i面值时的最少硬币。转移方程f[i] = min(f[i],f[j] - sum((a[k] / i)* (i / j - 1)));(j为i的因子,k为每只兔子价格)
为什么这么转移,因为比如说我们有三枚三元硬币,我们可以转换成一枚九元硬币。
很简单,比如说我们有一只兔子价格为28,用1元硬币去凑会用28枚(即f[1] = 28),用1、3去凑会有 f[3] = f[1] - 28 / 3 * (3 / 1 - 1) = 10枚硬币,用1,3,9去凑会有f[9] = f[3] - 28 / 9 * (9 / 3 - 1) = 4枚硬币。
其实转移是很简单的,但是发现i的范围是100,000 ,j是i的因子需要去转化,k是每只兔子,复杂度很高的。我们可以考虑省掉j。即我们用递推。
可以由f[j]倒推f[i]。
发现100000 内每个数 不停加本身,推到100000,再乘上50只兔子的复杂度才几千万,随便卡过。
我一开始是这么做的,于是4.6S过了(数据太亲民了)。
其实后面我想了一下还可以优化,因为比如说f[27]由f[9]推过去肯定比由f[3]推过去优,所以对于每个数我们只用去推它的质数倍数就好了。
设M =100,000,N = 50;
K 为 M内所有数乘以质数倍推到100000的复杂度(好像这个数才十万左右....)
筛素数(M loglog M),递推(N * K)所以复杂度是(M log log M + N * K)。然后就从4.6S降到了1.6S。话说数据是真亲民啊……
附上AC代码:
# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
using namespace std;
const int N = ;
const int M = 1e5 + ;
int a[N],n;
int f[M],ans,sum,maxn,cnt,p[M];
bool vis[M];
void shai(){
for(int i = ;i < M;i++){
if(!vis[i])p[++cnt] = i;
for(int j = ;j <= cnt;j++){
if(p[j] * i >= M)break;
vis[p[j] * i] = true;
if(i % p[j] == )break;
}
}
}
void Init(){
memset(f,0x3f3f3f3f,sizeof f);
}
int dp(int i,int j){
int ans = f[j];
for(int k = ;k <= n;k++){
ans -= (a[k] / i) * (i / j - );
}
return ans;
}
int main(){
Init(); scanf("%d",&n);
for(int i = ;i <= n;i++){
scanf("%d",&a[i]);sum += a[i];
maxn = max(maxn,a[i]);
}
f[] = sum;ans = f[];
for(int i = ;i <= maxn;i++){
f[i] = min(f[i],dp(i,));
ans = min(ans,f[i]);
}
shai();
for(int i = ;i <= maxn;i++){
for(int j = ;j <= cnt;j++){
if(p[j] * i > maxn)break;
f[p[j] * i] = min(f[p[j] * i],dp(p[j] * i,i));
ans = min(ans,f[p[j] * i]);
}
}
printf("%d\n",ans);
}
[Bzoj3233][Ahoi2013]找硬币[基础DP]的更多相关文章
- BZOJ3233:[AHOI2013]找硬币(DP)
Description 小蛇是金融部部长.最近她决定制造一系列新的货币.假设她要制造的货币的面值为x1,x2,x3… 那么x1必须为1,xb必须为xa的正整数倍(b>a).例如 1,5,125, ...
- [bzoj3233] [Ahoi2013]找硬币
一开始没什么思路...后来想到确定最大硬币面值就知道其他面值能取多少了..而且结果是可以由较小的面值转移过来的. f[i]表示最大面值为i时的最小硬币数.a[i]表示第i个物品的价钱. f[i]=mi ...
- BZOJ 3233: [Ahoi2013]找硬币( dp )
dp(x)表示最大面值为x时需要的最少硬币数. 枚举x的质因数p, dp(x) = min( dp(x/p) - (p-1) * sigma[a[i]/x] ). ----------------- ...
- [AHOI2013]找硬币(搜索)
[Ahoi2013]找硬币 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 348 Solved: 114[Submit][Status] Descri ...
- BZOJ 3233: [Ahoi2013]找硬币
BZOJ 3233: [Ahoi2013]找硬币 标签(空格分隔): OI-BZOJ OI-DP Time Limit: 10 Sec Memory Limit: 64 MB Description ...
- 【bzoj 3233】[Ahoi2013]找硬币 ——搜索
Description 小蛇是金融部部长.最近她决定制造一系列新的货币.假设她要制造的货币的面值为x1,x2,x3… 那么x1必须为1,xb必须为xa的正整数倍(b>a).例如 1,5,125, ...
- 【BZOJ 3233】 [Ahoi2013]找硬币
[题目 描述] 小蛇是金融部部长. 最近她决定制造一系列新的货币. 假设她要制造的货币 的面值为 x1, x2, x3… 那么 x1 必须为 1, xb 必须为 xa 的正整数倍(b>a). 例 ...
- 「kuangbin带你飞」专题十二 基础DP
layout: post title: 「kuangbin带你飞」专题十二 基础DP author: "luowentaoaa" catalog: true tags: mathj ...
- 找规律/数位DP HDOJ 4722 Good Numbers
题目传送门 /* 找规律/数位DP:我做的时候差一点做出来了,只是不知道最后的 is_one () http://www.cnblogs.com/crazyapple/p/3315436.html 数 ...
随机推荐
- QProcess执行带管道的shell命令
QStringList options; options << "-c" << "ls -l | grep a | sort"; QPr ...
- EOS Dapp体验报告
EOS Dapp体验报告 EOS通过并行链和DPOS的方式解决了延迟和数据吞吐量的难题. EOS能够实现每秒百万级的处理量,而目前比特币是每秒7笔,以太坊是30-40笔,EOS的这一超强能力吊打比特币 ...
- SQLite – 删除表
SQLite -删除表 SQLite DROP TABLE语句用于删除一个表定义和所有相关的数据,索引.触发器.约束和规范许可表. 你使用这个命令时必须小心,因为一旦一个表被删除然后表中所有可用的信息 ...
- day24-2 单例模式
目录 单例模式 类内部定义静态方法实现单例模式 装饰器实现单例模式 元类实现单例模式 单例模式 单例模式:基于某种方法实例化多次得到实例是同一个 当实例化多次得到的对象中存放的属性都一样的情况,应该将 ...
- 进程池_Pool
当需要创建子进程数量不多的时候,可以直接利用multiprocessing中的Process动态生成多个进程 但是如果是成百甚至上千个任务,手动地创建它的工作量很大,此时就可以利用到multiproc ...
- 尺取法 || emmmm
给定两个上升的数组,一个数组任取一个数,求两个数差的min 尺取法emm 也不知道对不对 #include <stdio.h> #include <stdlib.h> #def ...
- C++变量和基本类型
1. 如何选择类型的准则 当明确知晓数值不可能为负的时候,应该选择无符号类型. 使用int执行整数运算的时候,在实际应用中,short常常显得太小而long一般和int有一样的尺寸,如果数值超过了in ...
- 深度学总结:skip-gram pytorch实现
文章目录 skip-gram pytorch 朴素实现网络结构训练过程:使用nn.NLLLoss()batch的准备,为unsupervised,准备数据获取(center,contex)的pair: ...
- Word转html并移植到web项目
1.打开对应word文件 建议使用web视图查看文档 这样可以提前预览转转成html样式 2.如果有图片修改图片大小及格式 在web视图下,把图片调制适当大小,不然导出的html可能图片较小 3.点击 ...
- Java Thread.join()详解
一.使用方式. 二.为什么要用join()方法 三.join方法的作用 join 四.用实例来理解 打印结果: 打印结果: 五.从源码看join()方法 一.使用方式. join是Thread类的 ...