【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,长度分别为 ...
随机推荐
- 如何在centos操作系统上发布.net core的项目
环境:操作系统: centos 7.net core: 2.1.101 官方网站的示例地址: https://docs.microsoft.com/zh-cn/dotnet/core/linux-pr ...
- Qt Creator 更改默认构建目录到工程目录下
Qt Creator 更改默认构建目录到工程目录下 步骤 工具->选项->构建和运行->概要->Default build directory->去掉第一个". ...
- Python中的函数与变量
本节内容 函数的定义方法 函数功能 函数的返回值 函数的形参与实参 全局变量与局部变量 递归 函数的作用域 匿名函数lambda 函数式编程 常用内置函数 其他内置函数 函数 函数的定义方法 函数就相 ...
- SDCC2013大会笔记整理
2013-8-30 大会首日 百度移动云三大框架:Clouda.SiteApp.Appbuilder MBaaS解决高性能Server很难构建的问题. 百度开放云的区域运营服务于创业者 ------- ...
- JSF-页面导航
页面导航 1)导航处理涉及的术语: -动作值:触发动作事件的组件的action:EL方法表达式.字符串文字. -结果值:动作组件的action属性的:EL方法表达式的返回值.字符串文字:或结果组件的o ...
- C++判断字符串是否为空的一个小问题
刚才visual studio下处理一个函数字符串入参,判断入参字符串是否为空有点小问题. 接口函数声明是这样的:SHORT GETWFSINFPINKEYDETAIL(LPCTSTR strKeyN ...
- prometheus alert rules文件格式化
1.下载go(version>1.9,否则promtool工具不好使) https://golang.org/doc/install?download=go1.10.2.linux-amd64. ...
- Python测试远程端口连接时间
问题 最近自己服务器访问别人的服务器,有时候会报超时错误,有时候又能够正常访问别人服务器. 思路 最开始猜测是网络不稳定造成的,但是自己没有收集什么时候超时,什么时候能正常访问别人服务器的日志,搞网络 ...
- 洛谷 P1053 解题报告
P1053 篝火晚会 题目描述 佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了"小教官".在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会.一共有 ...
- Python_sniffer(网络嗅探器)
import socket import threading import time activeDegree=dict() flag=1 def main(): global activeDegre ...