【bzoj 3233】[Ahoi2013]找硬币 ——搜索
Description
Input
Output
一行,一个整数,表示最少付的钱币数。
Sample Input
25 102
Sample Output
HINT
样例解释:共有两只兔纸,价钱分别为25和102。现在小蛇构造1,25,100这样一组硬币序列,那么付第一只兔纸只需要一个面值为25的硬币,第二只兔纸需要一个面值为100的硬币和两个面值为1的硬币,总共两只兔纸需要付4个硬币。这也是所有方案中最少所需要付的硬币数。
1<=N<=50, 1<=ai<=100,000
题解:
听说是个DP?!
为什么我只会搜索……(我还信(sha)誓(bi)旦(zhi)旦(zhang)的和hz各位大佬说这绝对不能DP……)
显然每次都是选一个素数p,然后每个$a_{i}$可以表示成$a_{i}=k_{i}*p+rest_{i}$。那么$rest_{i}$是必须要用价值为1的硬币填,那么把$rest_{i}$减去,再给$a_{i}$除去$p$得到一个新数组,对于这个数组我们会发现它的处理和之前是一样,所以可以根据这个来dfs。
然后就是剪枝。神奇的估值。因为我们知道每一次选$p$为倍数,$rest_{i}$是必须用所谓的价值为1的去填,那么我们可以统计这个$\sum_{i=1}^{n}rest_{i}$并与已知答案比较即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
inline int min(int a,int b){return a<b?a:b;}
using namespace std;
const int N=;
inline int read(){
int s=,k=;char ch=getchar();
while(ch<''||ch>'') k=ch=='-'?-:k,ch=getchar();
while(ch>&&ch<='') s=s*+(ch^),ch=getchar();
return s*k;
}
int n;
int a[];
int ans=0x7fffffff;
int prim[];
bool vis[];
int k;
inline void init(){
for(int i=;i<=;i++){
if(!vis[i])
prim[++k]=i;
for(int j=;j<=k&&prim[j]*i<=;j++)
vis[i*prim[j]]=;
}
}
void dfs(int now,int sum,int tot){
int b[];
memcpy(b,a,sizeof(b));
for(int i=;i<=n;i++){
sum+=a[i]%now,a[i]/=now;
//if(a[i]==1) sum++,a[i]=0,from++;
}
// printf("now=%d sum=%d tot=%d a[n]=%d\n",now,sum,tot,a[n]);
if(a[n]){
int t=,z=;
int s=;
for(int q=;prim[q]<=a[n]+;q++) {
int i=prim[q];
z=;t=;
s=;
for(int j=;j<=n;j++){
if(a[j]<i) t++,z+=a[j];
s+=a[j]%i;
}
if(z+sum+n-t>=ans) break;
if(s+n-t+sum>=ans) continue;
dfs(i,sum,i*tot);
}
}
else{
for(int i=;i<=n;i++)
if(a[i]) sum++;
ans=min(ans,sum);
}
memcpy(a,b,sizeof(a));
}
int main(){ n=read();
init();
int need=;
for(int i=;i<=n;i++){ a[i]=read();
if(a[i]==){
i--,n--,need++;
}
}
if(n==){
printf("%d\n",need);
return ;
}
sort(a+,a++n); int t=,z=;
for(int q=;prim[q]<=a[n]+;q++){
int i=prim[q];
int sum=;
for(int j=;j<=n;j++){
sum+=a[j]%i;
if(a[j]<i&&j>t) t++,z+=a[j];
}
if(z+n-t>=ans) break;
if(sum+n-t>=ans) continue;
dfs(i,,i);//printf("sum[%d]=%d a[n]=%d\n",i,sum,a[n]);
}
printf("%d\n",ans+need);
}
话说自己至今才开搜索专栏……
【bzoj 3233】[Ahoi2013]找硬币 ——搜索的更多相关文章
- BZOJ 3233: [Ahoi2013]找硬币
BZOJ 3233: [Ahoi2013]找硬币 标签(空格分隔): OI-BZOJ OI-DP Time Limit: 10 Sec Memory Limit: 64 MB Description ...
- BZOJ 3233: [Ahoi2013]找硬币( dp )
dp(x)表示最大面值为x时需要的最少硬币数. 枚举x的质因数p, dp(x) = min( dp(x/p) - (p-1) * sigma[a[i]/x] ). ----------------- ...
- [Bzoj3233][Ahoi2013]找硬币[基础DP]
3233: [Ahoi2013]找硬币 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 924 Solved: 482[Submit][Status][ ...
- [AHOI2013]找硬币(搜索)
[Ahoi2013]找硬币 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 348 Solved: 114[Submit][Status] Descri ...
- 【BZOJ 3233】 [Ahoi2013]找硬币
[题目 描述] 小蛇是金融部部长. 最近她决定制造一系列新的货币. 假设她要制造的货币 的面值为 x1, x2, x3… 那么 x1 必须为 1, xb 必须为 xa 的正整数倍(b>a). 例 ...
- 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] 找硬币
Link: BZOJ 3233 传送门 Solution: 在本蒟蒻看来算是一道比较神的$dp$了 一开始转移方程都没看出来…… 首先,如果确定了最大面值,是能推出其他面值的所有可能值的 从而发现最大 ...
- 【刷题】BZOJ 4566 [Haoi2016]找相同字符
Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别为 ...
随机推荐
- 前端技术之_CSS详解第三天
前端技术之_CSS详解第三天 二.权重问题深入 2.1 同一个标签,携带了多个类名,有冲突: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 ...
- visio2010去除直线交叉处的歪曲
Visio画图时,两根直线交叉时,总是默认会出现一个跨线的标志,在2007前的版本,可以通过以下方式解决: 选中线条,然后菜单的格式->行为->连接线->跨线->添加-> ...
- jsonp学习
使用 JSONP 实现跨域通信:http://www.ibm.com/developerworks/cn/web/wa-aj-jsonp1/
- Django Web项目部署参考
环境准备:1.Python 2.7.*]2.pip3.sudo pip install django4.sudo aptitude show python-setuptools5.sudo aptit ...
- FPGA图像处理之行缓存(linebuffer)的设计一
FPGA图像处理之行缓存(linebuffer)的设计一 作者:OpenS_Lee 1 背景知识 在FPGA数字图像处理中,行缓存的使用非常频繁,例如我们需要图像矩阵操作的时候就需要进行缓存,例如图像 ...
- 前端打包工具——build release介绍
前言 对于前端开发者来说,资源打包是日常过程中一个必不可少的过程:目前我们大多数时候使用grunt.gulp.webpack这三个工具来完成这个工作:但是有一个特点就是我们没创建一个项目都要对应的去编 ...
- 判断某个方法是否存在,解析php函数function_exists (),method_exists()与is_callable()的区别
php函数function_exists (),method_exists() 与is_callable()的区别在哪? 先来讲下后两个:method_exists() 与is_callable(): ...
- python笔记:#011#循环
循环 目标 程序的三大流程 while 循环基本使用 break 和 continue while 循环嵌套 01. 程序的三大流程 在程序开发中,一共有三种流程方式: 顺序 -- 从上向下,顺序执行 ...
- python爬虫入门(六) Scrapy框架之原理介绍
Scrapy框架 Scrapy简介 Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬 ...
- 【问题】sql数据库报无效的数据证书,需重新安装
事情的经过: 今天打开sql2014数据库,没有成功运行,但是给我弹出一个"无效的数据证书,需要重新安装!"提示.什么情况.为什么,应该是前一天弄vs导致的.因为升级了vs2017 ...