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

时间:2022-08-31 19:35:27

Description

小蛇是金融部部长。最近她决定制造一系列新的货币。假设她要制造的货币的面值为x1,x2,x3… 那么x1必须为1,xb必须为xa的正整数倍(b>a)。例如 1,5,125,250就是一组合法的硬币序列,而1,5,100,125就不是。不知从哪一天开始,可爱的蛇爱上了一种萌物——兔纸!从此,小蛇便走上了遇上兔纸娃娃就买的不归路。某天,小蛇看到了N只可爱的兔纸,假设这N 只兔纸的价钱分别是a1,a2…aN。现在小蛇想知道,在哪一组合法的硬币序列下,买这N只兔纸所需要的硬币数最少。买兔纸时不能找零。

Input

第一行,一个整数N,表示兔纸的个数
第二行,N个用空格隔开的整数,分别为N只兔纸的价钱

Output

一行,一个整数,表示最少付的钱币数。

Sample Input

2
25 102

Sample Output

4

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]找硬币 ——搜索的更多相关文章

  1. BZOJ 3233&colon; &lbrack;Ahoi2013&rsqb;找硬币

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

  2. BZOJ 3233&colon; &lbrack;Ahoi2013&rsqb;找硬币&lpar; dp &rpar;

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

  3. &lbrack;Bzoj3233&rsqb;&lbrack;Ahoi2013&rsqb;找硬币&lbrack;基础DP&rsqb;

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

  4. &lbrack;AHOI2013&rsqb;找硬币(搜索)

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

  5. 【BZOJ 3233】 &lbrack;Ahoi2013&rsqb;找硬币

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

  6. BZOJ3233&colon;&lbrack;AHOI2013&rsqb;找硬币&lpar;DP&rpar;

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

  7. &lbrack;bzoj3233&rsqb; &lbrack;Ahoi2013&rsqb;找硬币

    一开始没什么思路...后来想到确定最大硬币面值就知道其他面值能取多少了..而且结果是可以由较小的面值转移过来的. f[i]表示最大面值为i时的最小硬币数.a[i]表示第i个物品的价钱. f[i]=mi ...

  8. &lbrack;BZOJ 3233&rsqb; 找硬币

    Link: BZOJ 3233 传送门 Solution: 在本蒟蒻看来算是一道比较神的$dp$了 一开始转移方程都没看出来…… 首先,如果确定了最大面值,是能推出其他面值的所有可能值的 从而发现最大 ...

  9. 【刷题】BZOJ 4566 &lbrack;Haoi2016&rsqb;找相同字符

    Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别为 ...

随机推荐

  1. JUnit报错需导入两个jar包

    <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-core</a ...

  2. php curl ftp上传 下载

    下载 //初始化 $ch=curl_init(); //文件的准确路径url curl_setopt($ch,CURLOPT_URL,"ftp://192.168.151.126/wwwro ...

  3. 在MyBook Live上部署svn

    一直以来都在用svn管理源代码,美中不足的是由于svn服务器端部署在本地,无法实现在异地迁入迁出程序,因此考虑将svn服务器部署在我的MyBook Live上. 一.部署svn 1.分别执行以下2条命 ...

  4. Jenkins2 - 下载与启动

    文章来自:http://www.ciandcd.com 文中的代码来自可以从github下载: https://github.com/ciandcd 本文将引导jenkins初学者安装和配置jenki ...

  5. build&period;gradle&lpar;Project&rpar; 和 build&period;gradle&lpar;Module&rpar; 的区别

    参考: http://*.com/questions/28295933/difference-between-build-gradleproject-and-build-gra ...

  6. andriod ADB命令的使用

    android ADB命令的使用 ADB是一个 客户端-服务器端 程序, 其中客户端是你用来操作的电脑, 服务器端是android设备. 先说安装方法, 电脑上需要安装客户端. 客户端包含在sdk里. ...

  7. 徒手用Java来写个Web服务器和框架吧&lt&semi;第二章&colon;Request和Response&gt&semi;

    徒手用Java来写个Web服务器和框架吧<第一章:NIO篇> 接上一篇,说到接受了请求,接下来就是解析请求构建Request对象,以及创建Response对象返回. 多有纰漏还请指出.省略 ...

  8. 一个基于JRTPLIB的轻量级RTSP客户端&lpar;myRTSPClient&rpar;——实现篇:(五)用户接口层之提取媒体流数据

    当RTSP客户端向RTSP服务端发送完PLAY命令后,RTSP服务端就会另外开启UDP端口(SDP协商定义的端口)发送RTP媒体流数据包.这些数据包之间会间隔一段时间(毫秒级)陆续被发送到RTSP客户 ...

  9. Hyperledger Fabric Model——超级账本组成模型

    超级账本组成模型 本文主要讲述Hyperledger Fabric的关键设计特性,并细述如何实现了一个全面的.可定制的企业级区块链解决方案: 资产定义--资产这里理解为任何具有货币价值的东西,它们都可 ...

  10. openvpn服务端与客户端网段互通

    http://www.softown.cn/post/140.html OpenVPN安装.配置教程 http://www.softown.cn/post/137.html openvpn的serve ...